From dbca022577e0da1f411ee84143d59c6c9d941969 Mon Sep 17 00:00:00 2001 From: rickyleung Date: Fri, 26 Apr 2024 17:29:18 +0800 Subject: [PATCH 6/7] [backport][AArch64] Stack probing for dynamic allocas in GlobalISel Reference: https://github.com/llvm/llvm-project/commit/c1140d49ec3363bf903e4c1dbf7a3f5e8c1b6523 Co-authored-by: Oliver Stannard --- .../llvm/CodeGen/GlobalISel/LegalizerHelper.h | 2 + .../CodeGen/GlobalISel/LegalizerHelper.cpp | 37 ++- .../AArch64/GISel/AArch64LegalizerInfo.cpp | 47 +++- .../AArch64/GISel/AArch64LegalizerInfo.h | 1 + .../GlobalISel/legalize-dyn-alloca.mir | 255 ++++++++++++++---- .../GlobalISel/legalizer-info-validation.mir | 7 + .../CodeGen/AArch64/stack-probing-dynamic.ll | 3 +- 7 files changed, 284 insertions(+), 68 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h index 9288091874cf..7abbd1f03f16 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -400,6 +400,8 @@ public: LegalizeResult lowerUnmergeValues(MachineInstr &MI); LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI); LegalizeResult lowerShuffleVector(MachineInstr &MI); + Register getDynStackAllocTargetPtr(Register SPReg, Register AllocSize, + Align Alignment, LLT PtrTy); LegalizeResult lowerDynStackAlloc(MachineInstr &MI); LegalizeResult lowerStackSave(MachineInstr &MI); LegalizeResult lowerStackRestore(MachineInstr &MI); diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 75d9789be4d0..5557456e706d 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -6777,21 +6777,12 @@ LegalizerHelper::lowerShuffleVector(MachineInstr &MI) { return Legalized; } -LegalizerHelper::LegalizeResult -LegalizerHelper::lowerDynStackAlloc(MachineInstr &MI) { - const auto &MF = *MI.getMF(); - const auto &TFI = *MF.getSubtarget().getFrameLowering(); - if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp) - return UnableToLegalize; - - Register Dst = MI.getOperand(0).getReg(); - Register AllocSize = MI.getOperand(1).getReg(); - Align Alignment = assumeAligned(MI.getOperand(2).getImm()); - - LLT PtrTy = MRI.getType(Dst); +Register LegalizerHelper::getDynStackAllocTargetPtr(Register SPReg, + Register AllocSize, + Align Alignment, + LLT PtrTy) { LLT IntPtrTy = LLT::scalar(PtrTy.getSizeInBits()); - Register SPReg = TLI.getStackPointerRegisterToSaveRestore(); auto SPTmp = MIRBuilder.buildCopy(PtrTy, SPReg); SPTmp = MIRBuilder.buildCast(IntPtrTy, SPTmp); @@ -6806,7 +6797,25 @@ LegalizerHelper::lowerDynStackAlloc(MachineInstr &MI) { Alloc = MIRBuilder.buildAnd(IntPtrTy, Alloc, AlignCst); } - SPTmp = MIRBuilder.buildCast(PtrTy, Alloc); + return MIRBuilder.buildCast(PtrTy, Alloc).getReg(0); +} + +LegalizerHelper::LegalizeResult +LegalizerHelper::lowerDynStackAlloc(MachineInstr &MI) { + const auto &MF = *MI.getMF(); + const auto &TFI = *MF.getSubtarget().getFrameLowering(); + if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp) + return UnableToLegalize; + + Register Dst = MI.getOperand(0).getReg(); + Register AllocSize = MI.getOperand(1).getReg(); + Align Alignment = assumeAligned(MI.getOperand(2).getImm()); + + LLT PtrTy = MRI.getType(Dst); + Register SPReg = TLI.getStackPointerRegisterToSaveRestore(); + Register SPTmp = + getDynStackAllocTargetPtr(SPReg, AllocSize, Alignment, PtrTy); + MIRBuilder.buildCopy(SPReg, SPTmp); MIRBuilder.buildCopy(Dst, SPTmp); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index f0130a0be29d..0dd2b4d48dd6 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -797,9 +797,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) return Query.Types[0] == p0 && Query.Types[1] == s64; }); - getActionDefinitionsBuilder({G_DYN_STACKALLOC, - G_STACKSAVE, - G_STACKRESTORE}).lower(); + getActionDefinitionsBuilder(G_DYN_STACKALLOC).custom(); + + getActionDefinitionsBuilder({G_STACKSAVE, G_STACKRESTORE}).lower(); if (ST.hasMOPS()) { // G_BZERO is not supported. Currently it is only emitted by @@ -993,6 +993,8 @@ bool AArch64LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, return legalizeMemOps(MI, Helper); case TargetOpcode::G_FCOPYSIGN: return legalizeFCopySign(MI, Helper); + case TargetOpcode::G_DYN_STACKALLOC: + return legalizeDynStackAlloc(MI, Helper); } llvm_unreachable("expected switch to return"); @@ -1689,3 +1691,42 @@ bool AArch64LegalizerInfo::legalizeFCopySign(MachineInstr &MI, MI.eraseFromParent(); return true; } + +bool AArch64LegalizerInfo::legalizeDynStackAlloc( + MachineInstr &MI, LegalizerHelper &Helper) const { + MachineFunction &MF = *MI.getParent()->getParent(); + MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; + MachineRegisterInfo &MRI = *MIRBuilder.getMRI(); + + // If stack probing is not enabled for this function, use the default + // lowering. + if (!MF.getFunction().hasFnAttribute("probe-stack") || + MF.getFunction().getFnAttribute("probe-stack").getValueAsString() != + "inline-asm") { + Helper.lowerDynStackAlloc(MI); + return true; + } + + Register Dst = MI.getOperand(0).getReg(); + Register AllocSize = MI.getOperand(1).getReg(); + Align Alignment = assumeAligned(MI.getOperand(2).getImm()); + + assert(MRI.getType(Dst) == LLT::pointer(0, 64) && + "Unexpected type for dynamic alloca"); + assert(MRI.getType(AllocSize) == LLT::scalar(64) && + "Unexpected type for dynamic alloca"); + + LLT PtrTy = MRI.getType(Dst); + Register SPReg = + Helper.getTargetLowering().getStackPointerRegisterToSaveRestore(); + Register SPTmp = + Helper.getDynStackAllocTargetPtr(SPReg, AllocSize, Alignment, PtrTy); + auto NewMI = + MIRBuilder.buildInstr(AArch64::PROBED_STACKALLOC_DYN, {}, {SPTmp}); + MRI.setRegClass(NewMI.getReg(0), &AArch64::GPR64commonRegClass); + MIRBuilder.setInsertPt(*NewMI->getParent(), NewMI); + MIRBuilder.buildCopy(Dst, SPTmp); + + MI.eraseFromParent(); + return true; +} \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h index c10f6e071ed4..94484ea59d15 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h @@ -58,6 +58,7 @@ private: bool legalizeCTTZ(MachineInstr &MI, LegalizerHelper &Helper) const; bool legalizeMemOps(MachineInstr &MI, LegalizerHelper &Helper) const; bool legalizeFCopySign(MachineInstr &MI, LegalizerHelper &Helper) const; + bool legalizeDynStackAlloc(MachineInstr &MI, LegalizerHelper &Helper) const; const AArch64Subtarget *ST; }; } // End llvm namespace. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-dyn-alloca.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-dyn-alloca.mir index e9188fb89f69..882c7468e70f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-dyn-alloca.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-dyn-alloca.mir @@ -19,6 +19,21 @@ ret i128* %addr } + define i8* @test_simple_alloca_stack_probing(i32 %numelts) "probe-stack"="inline-asm" { + %addr = alloca i8, i32 %numelts + ret i8* %addr + } + + define i8* @test_aligned_alloca_stack_probing(i32 %numelts) "probe-stack"="inline-asm" { + %addr = alloca i8, i32 %numelts, align 32 + ret i8* %addr + } + + define i128* @test_natural_alloca_stack_probing(i32 %numelts) "probe-stack"="inline-asm" { + %addr = alloca i128, i32 %numelts + ret i128* %addr + } + ... --- name: test_simple_alloca @@ -37,22 +52,23 @@ body: | ; CHECK-LABEL: name: test_simple_alloca ; CHECK: liveins: $w0 - ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) - ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]] - ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 - ; CHECK: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[MUL]], [[C1]] - ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 - ; CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] - ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp - ; CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) - ; CHECK: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] - ; CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[SUB]](s64) - ; CHECK: $sp = COPY [[INTTOPTR]](p0) - ; CHECK: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) - ; CHECK: $x0 = COPY [[COPY2]](p0) - ; CHECK: RET_ReallyLR implicit $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) + ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]] + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[MUL]], [[C1]] + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] + ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[SUB]](s64) + ; CHECK-NEXT: $sp = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: $x0 = COPY [[COPY2]](p0) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(s32) = COPY $w0 %3:_(s64) = G_CONSTANT i64 1 %1:_(s64) = G_ZEXT %0(s32) @@ -83,24 +99,25 @@ body: | ; CHECK-LABEL: name: test_aligned_alloca ; CHECK: liveins: $w0 - ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) - ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]] - ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 - ; CHECK: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[MUL]], [[C1]] - ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 - ; CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] - ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp - ; CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) - ; CHECK: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] - ; CHECK: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 -32 - ; CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[SUB]], [[C3]] - ; CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND1]](s64) - ; CHECK: $sp = COPY [[INTTOPTR]](p0) - ; CHECK: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) - ; CHECK: $x0 = COPY [[COPY2]](p0) - ; CHECK: RET_ReallyLR implicit $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) + ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]] + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[MUL]], [[C1]] + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] + ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 -32 + ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[SUB]], [[C3]] + ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND1]](s64) + ; CHECK-NEXT: $sp = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: $x0 = COPY [[COPY2]](p0) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(s32) = COPY $w0 %3:_(s64) = G_CONSTANT i64 1 %1:_(s64) = G_ZEXT %0(s32) @@ -131,22 +148,23 @@ body: | ; CHECK-LABEL: name: test_natural_alloca ; CHECK: liveins: $w0 - ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) - ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]] - ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 - ; CHECK: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[MUL]], [[C1]] - ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 - ; CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] - ; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp - ; CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) - ; CHECK: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] - ; CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[SUB]](s64) - ; CHECK: $sp = COPY [[INTTOPTR]](p0) - ; CHECK: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) - ; CHECK: $x0 = COPY [[COPY2]](p0) - ; CHECK: RET_ReallyLR implicit $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) + ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]] + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[MUL]], [[C1]] + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] + ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[SUB]](s64) + ; CHECK-NEXT: $sp = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: $x0 = COPY [[COPY2]](p0) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(s32) = COPY $w0 %3:_(s64) = G_CONSTANT i64 16 %1:_(s64) = G_ZEXT %0(s32) @@ -160,3 +178,140 @@ body: | RET_ReallyLR implicit $x0 ... +--- +name: test_simple_alloca_stack_probing +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '$w0' } +frameInfo: + maxAlignment: 1 +stack: + - { id: 0, name: addr, type: variable-sized, alignment: 1 } +machineFunctionInfo: {} +body: | + bb.1 (%ir-block.0): + liveins: $w0 + ; CHECK-LABEL: name: test_simple_alloca_stack_probing + ; CHECK: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]], [[C]](s64) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[SHL]], [[C1]] + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] + ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:gpr64common(p0) = G_INTTOPTR [[SUB]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: PROBED_STACKALLOC_DYN [[INTTOPTR]](p0), implicit-def $sp, implicit-def $nzcv, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY2]](p0) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 + %0:_(s32) = COPY $w0 + %1:_(s64) = G_ZEXT %0(s32) + %9:_(s64) = G_CONSTANT i64 0 + %2:_(s64) = G_SHL %1, %9(s64) + %4:_(s64) = G_CONSTANT i64 15 + %5:_(s64) = nuw G_ADD %2, %4 + %6:_(s64) = G_CONSTANT i64 -16 + %7:_(s64) = G_AND %5, %6 + %8:_(p0) = G_DYN_STACKALLOC %7(s64), 1 + $x0 = COPY %8(p0) + RET_ReallyLR implicit $x0 +... +--- +name: test_aligned_alloca_stack_probing +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '$w0' } +frameInfo: + maxAlignment: 32 +stack: + - { id: 0, name: addr, type: variable-sized, alignment: 32 } +machineFunctionInfo: {} +body: | + bb.1 (%ir-block.0): + liveins: $w0 + ; CHECK-LABEL: name: test_aligned_alloca_stack_probing + ; CHECK: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]], [[C]](s64) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[SHL]], [[C1]] + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] + ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 -32 + ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[SUB]], [[C3]] + ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:gpr64common(p0) = G_INTTOPTR [[AND1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: PROBED_STACKALLOC_DYN [[INTTOPTR]](p0), implicit-def $sp, implicit-def $nzcv, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY2]](p0) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 + %0:_(s32) = COPY $w0 + %1:_(s64) = G_ZEXT %0(s32) + %9:_(s64) = G_CONSTANT i64 0 + %2:_(s64) = G_SHL %1, %9(s64) + %4:_(s64) = G_CONSTANT i64 15 + %5:_(s64) = nuw G_ADD %2, %4 + %6:_(s64) = G_CONSTANT i64 -16 + %7:_(s64) = G_AND %5, %6 + %8:_(p0) = G_DYN_STACKALLOC %7(s64), 32 + $x0 = COPY %8(p0) + RET_ReallyLR implicit $x0 +... +--- +name: test_natural_alloca_stack_probing +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '$w0' } +frameInfo: + maxAlignment: 1 +stack: + - { id: 0, name: addr, type: variable-sized, alignment: 1 } +machineFunctionInfo: {} +body: | + bb.1 (%ir-block.0): + liveins: $w0 + ; CHECK-LABEL: name: test_natural_alloca_stack_probing + ; CHECK: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]], [[C]](s64) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 15 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = nuw G_ADD [[SHL]], [[C1]] + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -16 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ADD]], [[C2]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $sp + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY1]](p0) + ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[PTRTOINT]], [[AND]] + ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:gpr64common(p0) = G_INTTOPTR [[SUB]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[INTTOPTR]](p0) + ; CHECK-NEXT: PROBED_STACKALLOC_DYN [[INTTOPTR]](p0), implicit-def $sp, implicit-def $nzcv, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY2]](p0) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 + %0:_(s32) = COPY $w0 + %1:_(s64) = G_ZEXT %0(s32) + %9:_(s64) = G_CONSTANT i64 4 + %2:_(s64) = G_SHL %1, %9(s64) + %4:_(s64) = G_CONSTANT i64 15 + %5:_(s64) = nuw G_ADD %2, %4 + %6:_(s64) = G_CONSTANT i64 -16 + %7:_(s64) = G_AND %5, %6 + %8:_(p0) = G_DYN_STACKALLOC %7(s64), 1 + $x0 = COPY %8(p0) + RET_ReallyLR implicit $x0 +... \ No newline at end of file diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 461161f5b338..efae9b66b53d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -652,6 +652,13 @@ # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to [[DYN_STACKALLOC]] # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: G_STACKSAVE (opcode [[STACKSAVE:[0-9]+]]): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: G_STACKRESTORE (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to [[STACKSAVE]] +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: G_STRICT_FADD (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined diff --git a/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll b/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll index 4d9ef77f7a0d..ad9cdbe92b23 100644 --- a/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll +++ b/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple aarch64-none-eabi < %s -verify-machineinstrs | FileCheck %s +; RUN: llc -mtriple aarch64-none-eabi < %s -verify-machineinstrs | FileCheck %s +; RUN: llc -mtriple aarch64-none-eabi < %s -verify-machineinstrs -global-isel -global-isel-abort=2 | FileCheck %s ; Dynamically-sized allocation, needs a loop which can handle any size at ; runtime. The final iteration of the loop will temporarily put SP below the -- 2.42.0.windows.2