[llvm-branch-commits] [llvm] 8b89bc0 - [WebAssembly] Don't fold frame offset for global addresses

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 1 13:57:00 PST 2020


Author: Julien Jorge
Date: 2020-12-01T13:56:00-08:00
New Revision: 8b89bc0de0e190be04991a9622c5866a2e93ef6d

URL: https://github.com/llvm/llvm-project/commit/8b89bc0de0e190be04991a9622c5866a2e93ef6d
DIFF: https://github.com/llvm/llvm-project/commit/8b89bc0de0e190be04991a9622c5866a2e93ef6d.diff

LOG: [WebAssembly] Don't fold frame offset for global addresses

When machine instructions are in the form of
```
%0 = CONST_I32 @str
%1 = ADD_I32 %stack.0, %0
%2 = LOAD 0, 0, %1
```

In the `ADD_I32` instruction, it is possible to fold it if `%0` is a
`CONST_I32` from an immediate number. But in this case it is a global
address, so we shouldn't do that. But we haven't checked if the operand
of `ADD` is an immediate so far. This fixes the problem. (The case
applies the same for `ADD_I64` and `CONST_I64` instructions.)

Fixes https://bugs.llvm.org/show_bug.cgi?id=47944.

Patch by Julien Jorge (jjorge at quarkslab.com)

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D90577

(cherry picked from commit 0fca6517118d435f9c2d7afe6135fd5f357509b5)

Added: 
    

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
    llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
    llvm/test/CodeGen/WebAssembly/userstack.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
index 5ff0d73534a6..085910f01ee6 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -328,7 +328,9 @@ defm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
 } // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1
 
 def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)),
-          (CONST_I32 tglobaladdr:$addr)>, Requires<[IsNotPIC]>;
+          (CONST_I32 tglobaladdr:$addr)>, Requires<[IsNotPIC, HasAddr32]>;
+def : Pat<(i64 (WebAssemblywrapper tglobaladdr:$addr)),
+          (CONST_I64 tglobaladdr:$addr)>, Requires<[IsNotPIC, HasAddr64]>;
 
 def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)),
           (GLOBAL_GET_I32 tglobaladdr:$addr)>, Requires<[IsPIC]>;

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
index 130589c9df8c..6b6394a58339 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
@@ -101,10 +101,12 @@ void WebAssemblyRegisterInfo::eliminateFrameIndex(
               WebAssemblyFrameLowering::getOpcConst(MF) &&
             MRI.hasOneNonDBGUse(Def->getOperand(0).getReg())) {
           MachineOperand &ImmMO = Def->getOperand(1);
-          ImmMO.setImm(ImmMO.getImm() + uint32_t(FrameOffset));
-          MI.getOperand(FIOperandNum)
-              .ChangeToRegister(FrameRegister, /*isDef=*/false);
-          return;
+          if (ImmMO.isImm()) {
+            ImmMO.setImm(ImmMO.getImm() + uint32_t(FrameOffset));
+            MI.getOperand(FIOperandNum)
+                .ChangeToRegister(FrameRegister, /*isDef=*/false);
+            return;
+          }
         }
       }
     }

diff  --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll
index dec202ea6af9..3d0e0d8c86a0 100644
--- a/llvm/test/CodeGen/WebAssembly/userstack.ll
+++ b/llvm/test/CodeGen/WebAssembly/userstack.ll
@@ -328,6 +328,22 @@ define void @inline_asm() {
   ret void
 }
 
+; We optimize the format of "frame offset + operand" by folding it, but this is
+; only possible when that operand is an immediate. In this example it is a
+; global address, so we should not fold it.
+; CHECK-LABEL: frame_offset_with_global_address
+; CHECK: i[[PTR]].const ${{.*}}=, str
+ at str = local_unnamed_addr global [3 x i8] c"abc", align 16
+define i8 @frame_offset_with_global_address() {
+  %1 = alloca i8, align 4
+  %2 = ptrtoint i8* %1 to i32
+  ;; Here @str is a global address and not an immediate, so cannot be folded
+  %3 = getelementptr [3 x i8], [3 x i8]* @str, i32 0, i32 %2
+  %4 = load i8, i8* %3, align 8
+  %5 = and i8 %4, 67
+  ret i8 %5
+}
+
 ; CHECK: .globaltype	__stack_pointer, i[[PTR]]{{$}}
 
 ; TODO: test over-aligned alloca


        


More information about the llvm-branch-commits mailing list