From: Julien Jorge Date: Mon, 2 Nov 2020 01:29:26 +0000 (-0800) Subject: [WebAssembly] Don't fold frame offset for global addresses X-Git-Tag: llvmorg-13-init~7170 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0fca6517118d435f9c2d7afe6135fd5f357509b5;p=platform%2Fupstream%2Fllvm.git [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@quarkslab.com) Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D90577 --- diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp index 130589c..6b6394a 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 dec202e..3d0e0d8 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 +@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