WebAssembly: don't optimize frameindex store
authorJF Bastien <jfb@google.com>
Sat, 30 Jan 2016 14:11:26 +0000 (14:11 +0000)
committerJF Bastien <jfb@google.com>
Sat, 30 Jan 2016 14:11:26 +0000 (14:11 +0000)
The previous code was incorrect (can't getReg a frameindex). We could instead optimize it to reduce tree height, but I'm not sure that's worthwhile yet because we then try to eliminate the frameindex.

This patch also fixes frame index elimination for operations which may load or store: it used to assume the base was operand 2 and immediate offset operand 1. That's not true for stores, where they're 4 and 3.

llvm-svn: 259305

llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
llvm/lib/Target/WebAssembly/WebAssemblyStoreResults.cpp
llvm/test/CodeGen/WebAssembly/store-results.ll

index 46f271c..3397f59 100644 (file)
@@ -74,8 +74,9 @@ void WebAssemblyRegisterInfo::eliminateFrameIndex(
       // generate broken code.
       report_fatal_error("Memory offset field overflow");
     }
-    MI.getOperand(1).setImm(Offset);
-    MI.getOperand(2).ChangeToRegister(WebAssembly::SP32, /*IsDef=*/false);
+    MI.getOperand(FIOperandNum - 1).setImm(Offset);
+    MI.getOperand(FIOperandNum)
+        .ChangeToRegister(WebAssembly::SP32, /*IsDef=*/false);
   } else {
     // Otherwise create an i32.add SP, offset and make it the operand.
     auto &MRI = MF.getRegInfo();
index 5368ab7..4035eae 100644 (file)
@@ -134,10 +134,17 @@ bool WebAssemblyStoreResults::runOnMachineFunction(MachineFunction &MF) {
       case WebAssembly::STORE_F64:
       case WebAssembly::STORE_I32:
       case WebAssembly::STORE_I64: {
-        unsigned ToReg = MI.getOperand(0).getReg();
-        unsigned FromReg =
-            MI.getOperand(WebAssembly::StoreValueOperandNo).getReg();
-        Changed |= ReplaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT);
+        const auto &Stored = MI.getOperand(WebAssembly::StoreValueOperandNo);
+        if (Stored.isReg()) {
+          unsigned ToReg = MI.getOperand(0).getReg();
+          unsigned FromReg = Stored.getReg();
+          Changed |= ReplaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT);
+        } else if (Stored.isFI()) {
+          break;
+        } else {
+          report_fatal_error(
+              "Store results: store not consuming reg or frame index");
+        }
         break;
       }
       case WebAssembly::CALL_I32:
index 488579a..5590099 100644 (file)
@@ -59,3 +59,13 @@ for.body5.i:
 for.cond.cleanup4.i:
   ret void
 }
+
+; CHECK-LABEL: fi_ret:
+; CHECK: i32.store $discard=,
+define hidden i8* @fi_ret(i8** %addr) {
+entry:
+  %buf = alloca [27 x i8], align 16
+  %0 = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0
+  store i8* %0, i8** %addr
+  ret i8* %0
+}