[llvm] CodeGen: Fix bypassing legality checks for IMPLICIT_DEF rematerialization (PR #73934)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 05:16:08 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-regalloc
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
It's permitted to have extra implicit-def operands of the same main register
after the main register def. If there are implicit operands, use the standard
legality checks which verify the operand contents.
Depends #<!-- -->73933
---
Full diff: https://github.com/llvm/llvm-project/pull/73934.diff
6 Files Affected:
- (modified) llvm/include/llvm/CodeGen/TargetInstrInfo.h (+2-1)
- (modified) llvm/lib/CodeGen/LiveRangeEdit.cpp (+1-1)
- (modified) llvm/lib/Target/X86/X86InstrInfo.cpp (+3-1)
- (added) llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.ll (+125)
- (added) llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir (+119)
- (added) llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir (+92)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 58355a32315b235..4a2b7e7c379d683 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -140,7 +140,8 @@ class TargetInstrInfo : public MCInstrInfo {
/// registers so that the instructions result is independent of the place
/// in the function.
bool isTriviallyReMaterializable(const MachineInstr &MI) const {
- return MI.getOpcode() == TargetOpcode::IMPLICIT_DEF ||
+ return (MI.getOpcode() == TargetOpcode::IMPLICIT_DEF &&
+ MI.getNumOperands() == 1) ||
(MI.getDesc().isRematerializable() &&
isReallyTriviallyReMaterializable(MI));
}
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp
index ff49e080090c2bd..0203034b5a01474 100644
--- a/llvm/lib/CodeGen/LiveRangeEdit.cpp
+++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp
@@ -190,7 +190,7 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB,
// DestReg of the cloned instruction cannot be Dead. Set isDead of DestReg
// to false anyway in case the isDead flag of RM.OrigMI's dest register
// is true.
- (*--MI).getOperand(0).setIsDead(false);
+ (*--MI).clearRegisterDeads(DestReg);
Rematted.insert(RM.ParentVNI);
++NumReMaterialization;
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index b75c00effead01f..70ef1c32a4dff6e 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -782,7 +782,9 @@ bool X86InstrInfo::isReallyTriviallyReMaterializable(
// flag set.
llvm_unreachable("Unknown rematerializable operation!");
break;
-
+ case X86::IMPLICIT_DEF:
+ // Defer to generic logic.
+ break;
case X86::LOAD_STACK_GUARD:
case X86::AVX1_SETALLONES:
case X86::AVX2_SETALLONES:
diff --git a/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.ll b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.ll
new file mode 100644
index 000000000000000..bc26eca6f27ef8e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.ll
@@ -0,0 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=arm64-apple-macosx10.13.0 -mcpu=apple-m1 < %s | FileCheck %s
+
+ at .str = external constant [9 x i8]
+
+define void @_ZN38SanitizerCommonInterceptors_Scanf_Test8TestBodyEv(ptr %.str.40, ptr %.str.41, ptr %.str.42, ptr %.str.43, ptr %.str.44, ptr %.str.45, ptr nocapture writeonly %.str.47) nounwind {
+; CHECK-LABEL: _ZN38SanitizerCommonInterceptors_Scanf_Test8TestBodyEv:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub sp, sp, #128
+; CHECK-NEXT: stp x28, x27, [sp, #32] ; 16-byte Folded Spill
+; CHECK-NEXT: stp x26, x25, [sp, #48] ; 16-byte Folded Spill
+; CHECK-NEXT: stp x24, x23, [sp, #64] ; 16-byte Folded Spill
+; CHECK-NEXT: stp x22, x21, [sp, #80] ; 16-byte Folded Spill
+; CHECK-NEXT: stp x20, x19, [sp, #96] ; 16-byte Folded Spill
+; CHECK-NEXT: stp x29, x30, [sp, #112] ; 16-byte Folded Spill
+; CHECK-NEXT: mov x24, x6
+; CHECK-NEXT: mov x19, x5
+; CHECK-NEXT: mov x20, x4
+; CHECK-NEXT: mov x21, x3
+; CHECK-NEXT: mov x22, x2
+; CHECK-NEXT: mov x23, x1
+; CHECK-NEXT: mov x25, x0
+; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #1 ; =0x1
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: mov w28, #4 ; =0x4
+; CHECK-NEXT: stp x28, x28, [sp, #8]
+; CHECK-NEXT: str x28, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: stp x28, xzr, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: mov w27, #8 ; =0x8
+; CHECK-NEXT: str x27, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: mov w26, #1 ; =0x1
+; CHECK-NEXT: stp xzr, x26, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: str x26, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: str x28, [sp]
+; CHECK-NEXT: Lloh0:
+; CHECK-NEXT: adrp x26, _.str at GOTPAGE
+; CHECK-NEXT: Lloh1:
+; CHECK-NEXT: ldr x26, [x26, _.str at GOTPAGEOFF]
+; CHECK-NEXT: mov x0, x26
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL9testScanfPKcjz
+; CHECK-NEXT: str wzr, [x24]
+; CHECK-NEXT: str x27, [sp]
+; CHECK-NEXT: mov x0, x25
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: str x28, [sp]
+; CHECK-NEXT: mov x0, x23
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: str x28, [sp]
+; CHECK-NEXT: mov x0, x22
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: str x28, [sp]
+; CHECK-NEXT: mov x0, x21
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: str x28, [sp]
+; CHECK-NEXT: mov x0, x20
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: mov x0, x19
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: mov x0, x26
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: mov w8, #1 ; =0x1
+; CHECK-NEXT: stp x8, xzr, [sp, #8]
+; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: mov x0, #0 ; =0x0
+; CHECK-NEXT: mov w1, #0 ; =0x0
+; CHECK-NEXT: bl __ZL20testScanfNoGnuMallocPKcjz
+; CHECK-NEXT: ldp x29, x30, [sp, #112] ; 16-byte Folded Reload
+; CHECK-NEXT: ldp x20, x19, [sp, #96] ; 16-byte Folded Reload
+; CHECK-NEXT: ldp x22, x21, [sp, #80] ; 16-byte Folded Reload
+; CHECK-NEXT: ldp x24, x23, [sp, #64] ; 16-byte Folded Reload
+; CHECK-NEXT: ldp x26, x25, [sp, #48] ; 16-byte Folded Reload
+; CHECK-NEXT: ldp x28, x27, [sp, #32] ; 16-byte Folded Reload
+; CHECK-NEXT: add sp, sp, #128
+; CHECK-NEXT: ret
+; CHECK-NEXT: .loh AdrpLdrGot Lloh0, Lloh1
+entry:
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr null, i32 1, i32 0)
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr null, i32 0, i32 4, i32 4, i32 4)
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr null, i32 0, i32 4, i32 0)
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr null, i32 0, i32 8)
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr null, i32 0, i32 0, i32 1)
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr null, i32 0, i32 1)
+ tail call void (ptr, i32, ...) @_ZL9testScanfPKcjz(ptr nonnull @.str, i32 0, i32 4)
+ store i32 0, ptr %.str.47, align 4
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr %.str.40, i32 0, i32 8)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr %.str.41, i32 0, i32 4)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr %.str.42, i32 0, i32 4)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr %.str.43, i32 0, i32 4)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr %.str.44, i32 0, i32 4)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr %.str.45, i32 0, i32 0)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr nonnull @.str, i32 0, i32 0)
+ tail call void (ptr, i32, ...) @_ZL20testScanfNoGnuMallocPKcjz(ptr null, i32 0, i32 0, i32 1, i32 0)
+ ret void
+}
+
+declare void @_ZL9testScanfPKcjz(ptr, i32, ...) local_unnamed_addr
+
+declare void @_ZL20testScanfNoGnuMallocPKcjz(ptr, i32, ...) local_unnamed_addr
diff --git a/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir
new file mode 100644
index 000000000000000..9040937d027df48
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir
@@ -0,0 +1,119 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -mtriple=arm64-apple-macosx -mcpu=apple-m1 -verify-regalloc -run-pass=greedy -o - %s | FileCheck %s
+---
+name: func
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6
+
+ ; CHECK-LABEL: name: func
+ ; CHECK: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64sp = IMPLICIT_DEF
+ ; CHECK-NEXT: dead [[DEF1:%[0-9]+]]:gpr32 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY $x2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr64 = COPY $x3
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr64 = COPY $x4
+ ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gpr64 = COPY $x5
+ ; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr64 = COPY $x6
+ ; CHECK-NEXT: undef [[MOVi32imm:%[0-9]+]].sub_32:gpr64 = MOVi32imm 4, implicit-def [[MOVi32imm]]
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: BL 0, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 24, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 16, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 16, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[DEF2:%[0-9]+]]:gpr64 = IMPLICIT_DEF
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 16, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: undef [[DEF3:%[0-9]+]].sub_32:gpr64 = IMPLICIT_DEF implicit-def [[DEF3]]
+ ; CHECK-NEXT: STRXui [[DEF3]], [[DEF]], 1 :: (store (s64) into stack + 8)
+ ; CHECK-NEXT: BL 0, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 16, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: STRXui [[MOVi32imm]], [[DEF]], 0 :: (store (s64) into stack)
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: STRWui undef [[MOVi32imm]].sub_32, [[COPY]], 0 :: (store (s32))
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: STRXui [[DEF2]], undef [[DEF]], 0 :: (store (s64) into stack)
+ ; CHECK-NEXT: $x0 = COPY [[COPY6]]
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: $x0 = COPY [[COPY5]]
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: $x0 = COPY [[COPY4]]
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: $x0 = COPY [[COPY3]]
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: $x0 = COPY [[COPY2]]
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: $x0 = COPY [[COPY1]]
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: undef [[DEF4:%[0-9]+]].sub_32:gpr64 = IMPLICIT_DEF implicit-def [[DEF4]]
+ ; CHECK-NEXT: STRXui [[DEF4]], undef [[DEF]], 1 :: (store (s64) into stack + 8)
+ ; CHECK-NEXT: ADJCALLSTACKUP 24, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: RET_ReallyLR
+ %0:gpr64sp = IMPLICIT_DEF
+ undef %13.sub_32:gpr64 = IMPLICIT_DEF implicit-def %13
+ dead %2:gpr32 = IMPLICIT_DEF
+ %3:gpr64common = COPY $x0
+ %4:gpr64 = COPY $x1
+ %5:gpr64 = COPY $x2
+ %6:gpr64 = COPY $x3
+ %7:gpr64 = COPY $x4
+ %8:gpr64 = COPY $x5
+ %9:gpr64 = COPY $x6
+ undef %11.sub_32:gpr64 = MOVi32imm 4, implicit-def %11
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ BL 0, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 24, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKUP 24, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 16, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKUP 16, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ %12:gpr64 = IMPLICIT_DEF
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 16, 0, implicit-def dead $sp, implicit $sp
+ STRXui %13, %0, 1 :: (store (s64) into stack + 8)
+ BL 0, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ADJCALLSTACKUP 16, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ STRXui %11, %0, 0 :: (store (s64) into stack)
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ STRWui undef %11.sub_32, %3, 0 :: (store (s32))
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ STRXui %12, undef %0, 0 :: (store (s64) into stack)
+ $x0 = COPY %9
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ $x0 = COPY %8
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ $x0 = COPY %7
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ $x0 = COPY %6
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ $x0 = COPY %5
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ $x0 = COPY %4
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ADJCALLSTACKDOWN 24, 0, implicit-def dead $sp, implicit $sp
+ STRXui %13, undef %0, 1 :: (store (s64) into stack + 8)
+ ADJCALLSTACKUP 24, 0, implicit-def dead $sp, implicit $sp
+ RET_ReallyLR
+
+...
diff --git a/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir b/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir
new file mode 100644
index 000000000000000..aa94a03786f54ac
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir
@@ -0,0 +1,92 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -mtriple=arm64-apple-macosx -mcpu=apple-m1 -stress-regalloc=4 -verify-regalloc -run-pass=greedy -o - %s | FileCheck %s
+
+--- |
+ define void @inst_stores_to_dead_spill_implicit_def_impdef() {
+ ret void
+ }
+
+ define void @inst_stores_to_dead_spill_movimm_impdef() {
+ ret void
+ }
+
+ declare void @foo(ptr, i32, ...)
+
+...
+
+# The IMPLICIT_DEf has an implicit-def of a different virtual register
+# than the main def, so it should not be unconditionally treated as
+# rematerializable.
+
+---
+name: inst_stores_to_dead_spill_implicit_def_impdef
+tracksRegLiveness: true
+frameInfo:
+ hasCalls: true
+body: |
+ bb.0:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: inst_stores_to_dead_spill_implicit_def_impdef
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: STRXui $x0, %stack.0, 0 :: (store (s64) into %stack.0)
+ ; CHECK-NEXT: dead undef [[COPY:%[0-9]+]].sub_32:gpr64 = COPY $x1
+ ; CHECK-NEXT: dead undef [[DEF:%[0-9]+]].sub_32:gpr64 = IMPLICIT_DEF implicit-def %6
+ ; CHECK-NEXT: STRXui %6, %stack.1, 0 :: (store (s64) into %stack.1)
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: BL @foo, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui %stack.0, 0 :: (load (s64) from %stack.0)
+ ; CHECK-NEXT: [[LDRXui1:%[0-9]+]]:gpr64 = LDRXui %stack.1, 0 :: (load (s64) from %stack.1)
+ ; CHECK-NEXT: STRXui [[LDRXui1]], [[LDRXui]], 1 :: (store (s64) into stack + 8)
+ ; CHECK-NEXT: STRXui undef %8:gpr64, [[LDRXui]], 0 :: (store (s64) into stack)
+ ; CHECK-NEXT: RET_ReallyLR
+ %0:gpr64sp = COPY $x0
+ undef %1.sub_32:gpr64 = COPY $x1
+ undef %2.sub_32:gpr64 = IMPLICIT_DEF implicit-def %1
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ BL @foo, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ STRXui %1, %0, 1 :: (store (s64) into stack + 8)
+ STRXui undef %1, %0, 0 :: (store (s64) into stack)
+ RET_ReallyLR
+
+...
+
+# Same function, except with a rematerializable mov imm instead of
+# IMPLICIT_DEF
+---
+name: inst_stores_to_dead_spill_movimm_impdef
+tracksRegLiveness: true
+frameInfo:
+ hasCalls: true
+body: |
+ bb.0:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: inst_stores_to_dead_spill_movimm_impdef
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: STRXui $x0, %stack.0, 0 :: (store (s64) into %stack.0)
+ ; CHECK-NEXT: dead undef [[COPY:%[0-9]+]].sub_32:gpr64 = COPY $x1
+ ; CHECK-NEXT: dead undef [[MOVi32imm:%[0-9]+]].sub_32:gpr64 = MOVi32imm 4, implicit-def %6
+ ; CHECK-NEXT: STRXui %6, %stack.1, 0 :: (store (s64) into %stack.1)
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: BL @foo, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui %stack.0, 0 :: (load (s64) from %stack.0)
+ ; CHECK-NEXT: [[LDRXui1:%[0-9]+]]:gpr64 = LDRXui %stack.1, 0 :: (load (s64) from %stack.1)
+ ; CHECK-NEXT: STRXui [[LDRXui1]], [[LDRXui]], 1 :: (store (s64) into stack + 8)
+ ; CHECK-NEXT: STRXui undef %8:gpr64, [[LDRXui]], 0 :: (store (s64) into stack)
+ ; CHECK-NEXT: RET_ReallyLR
+ %0:gpr64sp = COPY $x0
+ undef %1.sub_32:gpr64 = COPY $x1
+ undef %2.sub_32:gpr64 = MOVi32imm 4, implicit-def %1
+ ADJCALLSTACKDOWN 8, 0, implicit-def dead $sp, implicit $sp
+ BL @foo, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ADJCALLSTACKUP 8, 0, implicit-def dead $sp, implicit $sp
+ STRXui %1, %0, 1 :: (store (s64) into stack + 8)
+ STRXui undef %1, %0, 0 :: (store (s64) into stack)
+ RET_ReallyLR
+
+...
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/73934
More information about the llvm-commits
mailing list