[llvm] 1ca0808 - GlobalISel: Don't expand stacksave/stackrestore in IRTranslator
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 9 15:43:23 PDT 2023
Author: Matt Arsenault
Date: 2023-08-09T18:33:55-04:00
New Revision: 1ca0808db2c6393f4a79dcb57b89627eeefffffc
URL: https://github.com/llvm/llvm-project/commit/1ca0808db2c6393f4a79dcb57b89627eeefffffc
DIFF: https://github.com/llvm/llvm-project/commit/1ca0808db2c6393f4a79dcb57b89627eeefffffc.diff
LOG: GlobalISel: Don't expand stacksave/stackrestore in IRTranslator
In some (likely invalid edge cases anyway), it's not correct to
directly copy the stack pointer register.
Added:
llvm/test/CodeGen/AArch64/GlobalISel/stacksave-stackrestore.ll
llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
Modified:
llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
llvm/include/llvm/Support/TargetOpcodes.def
llvm/include/llvm/Target/GenericOpcodes.td
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
llvm/lib/Target/X86/X86LegalizerInfo.cpp
llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a568edd0e640d9..9288091874cf26 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -401,6 +401,8 @@ class LegalizerHelper {
LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI);
LegalizeResult lowerShuffleVector(MachineInstr &MI);
LegalizeResult lowerDynStackAlloc(MachineInstr &MI);
+ LegalizeResult lowerStackSave(MachineInstr &MI);
+ LegalizeResult lowerStackRestore(MachineInstr &MI);
LegalizeResult lowerExtract(MachineInstr &MI);
LegalizeResult lowerInsert(MachineInstr &MI);
LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index 67430a13aeea8c..623f3ce91e4ebb 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -769,6 +769,12 @@ HANDLE_TARGET_OPCODE(G_JUMP_TABLE)
/// Generic dynamic stack allocation.
HANDLE_TARGET_OPCODE(G_DYN_STACKALLOC)
+/// Generic stack pointer save.
+HANDLE_TARGET_OPCODE(G_STACKSAVE)
+
+/// Generic stack pointer restore.
+HANDLE_TARGET_OPCODE(G_STACKRESTORE)
+
/// Strict floating point instructions.
HANDLE_TARGET_OPCODE(G_STRICT_FADD)
HANDLE_TARGET_OPCODE(G_STRICT_FSUB)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 680d3223a95eab..4782d9d7b798a5 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -225,6 +225,18 @@ def G_DYN_STACKALLOC : GenericInstruction {
let hasSideEffects = true;
}
+def G_STACKSAVE : GenericInstruction {
+ let OutOperandList = (outs ptype0:$dst);
+ let InOperandList = (ins);
+ let hasSideEffects = true;
+}
+
+def G_STACKRESTORE : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptype0:$src);
+ let hasSideEffects = true;
+}
+
def G_FREEZE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index d81b634be87b1e..482057f167e238 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2229,31 +2229,12 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
return true;
}
case Intrinsic::stacksave: {
- // Save the stack pointer to the location provided by the intrinsic.
- Register Reg = getOrCreateVReg(CI);
- Register StackPtr = MF->getSubtarget()
- .getTargetLowering()
- ->getStackPointerRegisterToSaveRestore();
-
- // If the target doesn't specify a stack pointer, then fall back.
- if (!StackPtr)
- return false;
-
- MIRBuilder.buildCopy(Reg, StackPtr);
+ MIRBuilder.buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
return true;
}
case Intrinsic::stackrestore: {
- // Restore the stack pointer from the location provided by the intrinsic.
- Register Reg = getOrCreateVReg(*CI.getArgOperand(0));
- Register StackPtr = MF->getSubtarget()
- .getTargetLowering()
- ->getStackPointerRegisterToSaveRestore();
-
- // If the target doesn't specify a stack pointer, then fall back.
- if (!StackPtr)
- return false;
-
- MIRBuilder.buildCopy(StackPtr, Reg);
+ MIRBuilder.buildInstr(TargetOpcode::G_STACKRESTORE, {},
+ {getOrCreateVReg(*CI.getArgOperand(0))});
return true;
}
case Intrinsic::cttz:
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index e816da8bd967d1..afba4e185bb8ad 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -3502,6 +3502,10 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
return lowerShuffleVector(MI);
case G_DYN_STACKALLOC:
return lowerDynStackAlloc(MI);
+ case G_STACKSAVE:
+ return lowerStackSave(MI);
+ case G_STACKRESTORE:
+ return lowerStackRestore(MI);
case G_EXTRACT:
return lowerExtract(MI);
case G_INSERT:
@@ -6809,6 +6813,28 @@ LegalizerHelper::lowerDynStackAlloc(MachineInstr &MI) {
return Legalized;
}
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerStackSave(MachineInstr &MI) {
+ Register StackPtr = TLI.getStackPointerRegisterToSaveRestore();
+ if (!StackPtr)
+ return UnableToLegalize;
+
+ MIRBuilder.buildCopy(MI.getOperand(0), StackPtr);
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerStackRestore(MachineInstr &MI) {
+ Register StackPtr = TLI.getStackPointerRegisterToSaveRestore();
+ if (!StackPtr)
+ return UnableToLegalize;
+
+ MIRBuilder.buildCopy(StackPtr, MI.getOperand(0));
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::lowerExtract(MachineInstr &MI) {
auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index f94f7e268138af..819628213e3eb6 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -799,7 +799,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
return Query.Types[0] == p0 && Query.Types[1] == s64;
});
- getActionDefinitionsBuilder(G_DYN_STACKALLOC).lower();
+ getActionDefinitionsBuilder({G_DYN_STACKALLOC,
+ G_STACKSAVE,
+ G_STACKRESTORE}).lower();
if (ST.hasMOPS()) {
// G_BZERO is not supported. Currently it is only emitted by
diff --git a/llvm/lib/Target/X86/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/X86LegalizerInfo.cpp
index a4a247f85f3d72..104461cff0a91b 100644
--- a/llvm/lib/Target/X86/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/X86LegalizerInfo.cpp
@@ -528,6 +528,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
// memory intrinsics
getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
+ getActionDefinitionsBuilder({G_DYN_STACKALLOC,
+ G_STACKSAVE,
+ G_STACKRESTORE}).lower();
+
// fp intrinsics
getActionDefinitionsBuilder(G_INTRINSIC_ROUNDEVEN)
.scalarize(0)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
index 5f3544add39844..575cd6b874e356 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
@@ -2392,8 +2392,8 @@ declare ptr @llvm.stacksave()
declare void @llvm.stackrestore(ptr)
define void @test_stacksaverestore() {
; CHECK-LABEL: name: test_stacksaverestore
- ; CHECK: [[SAVE:%[0-9]+]]:_(p0) = COPY $sp
- ; CHECK-NEXT: $sp = COPY [[SAVE]](p0)
+ ; CHECK: [[SAVE:%[0-9]+]]:_(p0) = G_STACKSAVE
+ ; CHECK-NEXT: G_STACKRESTORE [[SAVE]]
; CHECK-NEXT: RET_ReallyLR
%sp = call ptr @llvm.stacksave()
call void @llvm.stackrestore(ptr %sp)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index 55dcbc255e69e6..89c22d79c9332a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -648,7 +648,15 @@
# DEBUG-NEXT: G_JUMP_TABLE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
-# DEBUG-NEXT: G_DYN_STACKALLOC (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: G_DYN_STACKALLOC (opcode [[DYN_STACKALLOC:[0-9]+]]): 2 type indices, 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_STACKSAVE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# 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_STACKRESTORE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# 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_STRICT_FADD (opcode {{[0-9]+}}): 1 type index, 0 imm indices
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/stacksave-stackrestore.ll b/llvm/test/CodeGen/AArch64/GlobalISel/stacksave-stackrestore.ll
new file mode 100644
index 00000000000000..16bf85af9c17b3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/stacksave-stackrestore.ll
@@ -0,0 +1,35 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -global-isel=1 -mtriple=aarch64-linux-gnu -o - %s | FileCheck %s
+
+declare void @use_addr(ptr)
+declare ptr @llvm.stacksave.p0()
+declare void @llvm.stackrestore.p0(ptr)
+
+define void @test_scoped_alloca(i64 %n) {
+; CHECK-LABEL: test_scoped_alloca:
+; CHECK: // %bb.0:
+; CHECK-NEXT: stp x29, x30, [sp, #-32]! // 16-byte Folded Spill
+; CHECK-NEXT: str x19, [sp, #16] // 8-byte Folded Spill
+; CHECK-NEXT: mov x29, sp
+; CHECK-NEXT: .cfi_def_cfa w29, 32
+; CHECK-NEXT: .cfi_offset w19, -16
+; CHECK-NEXT: .cfi_offset w30, -24
+; CHECK-NEXT: .cfi_offset w29, -32
+; CHECK-NEXT: add x9, x0, #15
+; CHECK-NEXT: mov x8, sp
+; CHECK-NEXT: and x9, x9, #0xfffffffffffffff0
+; CHECK-NEXT: mov x19, sp
+; CHECK-NEXT: sub x0, x8, x9
+; CHECK-NEXT: mov sp, x0
+; CHECK-NEXT: bl use_addr
+; CHECK-NEXT: mov sp, x19
+; CHECK-NEXT: mov sp, x29
+; CHECK-NEXT: ldr x19, [sp, #16] // 8-byte Folded Reload
+; CHECK-NEXT: ldp x29, x30, [sp], #32 // 16-byte Folded Reload
+; CHECK-NEXT: ret
+ %sp = call ptr @llvm.stacksave.p0()
+ %addr = alloca i8, i64 %n
+ call void @use_addr(ptr %addr)
+ call void @llvm.stackrestore.p0(ptr %sp)
+ ret void
+}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll b/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
new file mode 100644
index 00000000000000..e86c04ee22dbd1
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -global-isel=1 -mtriple=x86_64-linux-gnu -o - %s | FileCheck %s
+
+declare void @use_addr(ptr)
+declare ptr @llvm.stacksave.p0()
+declare void @llvm.stackrestore.p0(ptr)
+
+define void @test_scoped_alloca(i64 %n) {
+; CHECK-LABEL: test_scoped_alloca:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rbp
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: .cfi_offset %rbp, -16
+; CHECK-NEXT: movq %rsp, %rbp
+; CHECK-NEXT: .cfi_def_cfa_register %rbp
+; CHECK-NEXT: pushq %rbx
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: .cfi_offset %rbx, -24
+; CHECK-NEXT: movq %rsp, %rbx
+; CHECK-NEXT: movq %rsp, %rax
+; CHECK-NEXT: imulq $1, %rdi, %rcx
+; CHECK-NEXT: addq $15, %rcx
+; CHECK-NEXT: andq $-16, %rcx
+; CHECK-NEXT: subq %rcx, %rax
+; CHECK-NEXT: movq %rax, %rsp
+; CHECK-NEXT: movq %rax, %rdi
+; CHECK-NEXT: callq use_addr
+; CHECK-NEXT: movq %rbx, %rsp
+; CHECK-NEXT: leaq -8(%rbp), %rsp
+; CHECK-NEXT: popq %rbx
+; CHECK-NEXT: popq %rbp
+; CHECK-NEXT: .cfi_def_cfa %rsp, 8
+; CHECK-NEXT: retq
+ %sp = call ptr @llvm.stacksave.p0()
+ %addr = alloca i8, i64 %n
+ call void @use_addr(ptr %addr)
+ call void @llvm.stackrestore.p0(ptr %sp)
+ ret void
+}
More information about the llvm-commits
mailing list