[MachineLICM] Recognize registers clobbered at EH landing pad entry (#122446)
EH landing pad entry implicitly clobbers target-specific exception
pointer and exception selector registers. The post-RA MachineLICM pass
needs to take these into account when deciding whether to hoist an
instruction out of the loop that initializes one of these registers.
Fixes: https://github.com/llvm/llvm-project/issues/122315
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index d13d41c..9ea0e5a 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -633,6 +633,19 @@
if (const uint32_t *Mask = BB->getBeginClobberMask(TRI))
applyBitsNotInRegMaskToRegUnitsMask(*TRI, RUClobbers, Mask);
+ // EH landing pads clobber exception pointer/selector registers.
+ if (BB->isEHPad()) {
+ const MachineFunction &MF = *BB->getParent();
+ const Constant *PersonalityFn = MF.getFunction().getPersonalityFn();
+ const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
+ if (MCRegister Reg = TLI.getExceptionPointerRegister(PersonalityFn))
+ for (MCRegUnit Unit : TRI->regunits(Reg))
+ RUClobbers.set(Unit);
+ if (MCRegister Reg = TLI.getExceptionSelectorRegister(PersonalityFn))
+ for (MCRegUnit Unit : TRI->regunits(Reg))
+ RUClobbers.set(Unit);
+ }
+
SpeculationState = SpeculateUnknown;
for (MachineInstr &MI : *BB)
ProcessMI(&MI, RUDefs, RUClobbers, StoredFIs, Candidates, CurLoop);
diff --git a/llvm/test/CodeGen/SystemZ/pr122315.ll b/llvm/test/CodeGen/SystemZ/pr122315.ll
new file mode 100644
index 0000000..b094d11
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/pr122315.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Verify that MachineLICM recognizes that EH landing pad entry clobbers %r6/%r7
+;
+; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
+
+declare i64 @personality(i64, i64, i64, ptr, ptr)
+declare void @callee(i64, i64, i64, i64, i64)
+declare void @panic()
+
+define void @test() uwtable personality ptr @personality {
+; CHECK-LABEL: test:
+; CHECK: .Lfunc_begin0:
+; CHECK-NEXT: .cfi_startproc
+; CHECK-NEXT: .cfi_personality 0, personality
+; CHECK-NEXT: .cfi_lsda 0, .Lexception0
+; CHECK-NEXT: # %bb.0: # %start
+; CHECK-NEXT: stmg %r6, %r15, 48(%r15)
+; CHECK-NEXT: .cfi_offset %r6, -112
+; CHECK-NEXT: .cfi_offset %r7, -104
+; CHECK-NEXT: .cfi_offset %r14, -48
+; CHECK-NEXT: .cfi_offset %r15, -40
+; CHECK-NEXT: aghi %r15, -160
+; CHECK-NEXT: .cfi_def_cfa_offset 320
+; CHECK-NEXT: .LBB0_1: # %bb1
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lghi %r2, 0
+; CHECK-NEXT: lghi %r3, 0
+; CHECK-NEXT: lghi %r4, 0
+; CHECK-NEXT: lghi %r5, 0
+; CHECK-NEXT: lghi %r6, 0
+; CHECK-NEXT: brasl %r14, callee@PLT
+; CHECK-NEXT: .Ltmp0:
+; CHECK-NEXT: brasl %r14, panic@PLT
+; CHECK-NEXT: .Ltmp1:
+; CHECK-NEXT: j .LBB0_3
+; CHECK-NEXT: .LBB0_2: # %bb3
+; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT: .Ltmp2:
+; CHECK-NEXT: j .LBB0_1
+; CHECK-NEXT: .LBB0_3: # %bb2
+; CHECK-NEXT: lmg %r6, %r15, 208(%r15)
+; CHECK-NEXT: br %r14
+start:
+ br label %bb1
+
+bb1:
+ call void @callee(i64 0, i64 0, i64 0, i64 0, i64 0)
+ invoke void @panic()
+ to label %bb2 unwind label %bb3
+
+bb2:
+ ret void
+
+bb3:
+ %lp = landingpad { ptr, i32 }
+ catch ptr null
+ br label %bb1
+}
+