[PATCH] D15941: [WebAssembly] Support combining GEP and FrameIndex offsets in memory operand offset field

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 7 10:58:53 PST 2016


dschuff updated this revision to Diff 44231.
dschuff marked an inline comment as done.
dschuff added a comment.

- Cast offset to unsigned type


http://reviews.llvm.org/D15941

Files:
  lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
  test/CodeGen/WebAssembly/userstack.ll

Index: test/CodeGen/WebAssembly/userstack.ll
===================================================================
--- test/CodeGen/WebAssembly/userstack.ll
+++ test/CodeGen/WebAssembly/userstack.ll
@@ -72,6 +72,27 @@
  ret void
 }
 
+define void @allocarray_inbounds() {
+ ; CHECK: i32.const [[L1:.+]]=, __stack_pointer
+ ; CHECK-NEXT: i32.load [[L1]]=, 0([[L1]])
+ ; CHECK-NEXT: i32.const [[L2:.+]]=, 32
+ ; CHECK-NEXT: i32.sub [[SP:.+]]=, [[L1]], [[L2]]
+ %r = alloca [5 x i32]
+ ; CHECK: i32.const $push[[L3:.+]]=, 1
+ ; CHECK: i32.store {{.*}}=, 12([[SP]]), $pop[[L3]]
+ %p = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 0
+ store i32 1, i32* %p
+ ; This store should have both the GEP and the FI folded into it.
+ ; CHECK-NEXT: i32.store {{.*}}=, 16([[SP]]), $pop
+ %p2 = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 1
+ store i32 1, i32* %p2
+ ; CHECK: i32.const [[L7:.+]]=, 32
+ ; CHECK-NEXT: i32.add [[SP]]=, [[SP]], [[L7]]
+ ; CHECK-NEXT: i32.const [[L8:.+]]=, __stack_pointer
+ ; CHECK-NEXT: i32.store [[SP]]=, 0([[L7]]), [[SP]]
+ ret void
+}
+
 define void @dynamic_alloca(i32 %alloc) {
  ; TODO: Support frame pointers
  ;%r = alloca i32, i32 %alloc
Index: lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
+++ lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
@@ -61,17 +61,23 @@
   MachineFunction &MF = *MBB.getParent();
   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
   const MachineFrameInfo& MFI = *MF.getFrameInfo();
-  int FrameOffset = MFI.getStackSize() + MFI.getObjectOffset(FrameIndex);
+  int64_t FrameOffset = MFI.getStackSize() + MFI.getObjectOffset(FrameIndex);
 
   if (MI.mayLoadOrStore()) {
     // If this is a load or store, make it relative to SP and fold the frame
-    // offset directly in
-    assert(MI.getOperand(1).getImm() == 0 &&
-           "Can't eliminate FI yet if offset is already set");
-    MI.getOperand(1).setImm(FrameOffset);
+    // offset directly in.
+    assert(FrameOffset >= 0 && MI.getOperand(1).getImm() >= 0);
+    int64_t Offset = MI.getOperand(1).getImm() + FrameOffset;
+
+    if (static_cast<uint64_t>(Offset) > std::numeric_limits<uint32_t>::max()) {
+      // If this happens the program is invalid, but better to error here than
+      // generate broken code.
+      report_fatal_error("Memory offset field overflow");
+    }
+    MI.getOperand(1).setImm(Offset);
     MI.getOperand(2).ChangeToRegister(WebAssembly::SP32, /*IsDef=*/false);
   } else {
-    // Otherwise create an i32.add SP, offset and make it the operand
+    // Otherwise create an i32.add SP, offset and make it the operand.
     auto &MRI = MF.getRegInfo();
     const auto *TII = MF.getSubtarget().getInstrInfo();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15941.44231.patch
Type: text/x-patch
Size: 2826 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160107/315fbae9/attachment.bin>


More information about the llvm-commits mailing list