diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -3221,6 +3221,10 @@ // assert(Offset < (1 << 24) && "unimplemented reg plus immediate"); const unsigned MaxEncodableValue = MaxEncoding << ShiftSize; + Register TmpReg = DestReg; + if (TmpReg == AArch64::XZR) + TmpReg = MBB.getParent()->getRegInfo().createVirtualRegister( + &AArch64::GPR64RegClass); do { uint64_t ThisVal = std::min(Offset, MaxEncodableValue); unsigned LocalShiftSize = 0; @@ -3230,7 +3234,11 @@ } assert((ThisVal >> ShiftSize) <= MaxEncoding && "Encoding cannot handle value that big"); - auto MBI = BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) + + Offset -= ThisVal << LocalShiftSize; + if (Offset == 0) + TmpReg = DestReg; + auto MBI = BuildMI(MBB, MBBI, DL, TII->get(Opc), TmpReg) .addReg(SrcReg) .addImm(Sign * (int)ThisVal); if (ShiftSize) @@ -3251,8 +3259,8 @@ BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_AddFP)) .addImm(Imm) .setMIFlag(Flag); - assert((Offset - Imm) == 0 && "Expected remaining offset to be zero to " - "emit a single SEH directive"); + assert(Offset == 0 && "Expected remaining offset to be zero to " + "emit a single SEH directive"); } else if (DestReg == AArch64::SP) { if (HasWinCFI) *HasWinCFI = true; @@ -3265,8 +3273,7 @@ *HasWinCFI = true; } - SrcReg = DestReg; - Offset -= ThisVal << LocalShiftSize; + SrcReg = TmpReg; } while (Offset); } diff --git a/llvm/test/CodeGen/AArch64/large-stack-cmp.ll b/llvm/test/CodeGen/AArch64/large-stack-cmp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/large-stack-cmp.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple=arm64-apple-ios %s -o - | FileCheck %s + +define void @foo() { +; CHECK-LABEL: foo: +; CHECK: adds [[TMP:x[0-9]+]], sp, +; CHECK: cmn [[TMP]], + +%var = alloca i32, i32 12 + %var2 = alloca i32, i32 1030 + %tst = icmp eq i32* %var, null + br i1 %tst, label %true, label %false + +true: + call void @bar() + ret void + +false: + call void @baz() + ret void +} + +declare void @bar() +declare void @baz()