[llvm] [ARM] Fix Machine Outliner crash when tBLXr uses non-tcGPR register (PR #200684)

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 4 03:04:13 PDT 2026


================
@@ -5827,9 +5827,11 @@ ARMBaseInstrInfo::getOutliningCandidateInfo(
     SetCandidateCallInfo(MachineOutlinerTailCall, Costs.CallTailCall);
   } else if (LastInstrOpcode == ARM::BL || LastInstrOpcode == ARM::BLX ||
              LastInstrOpcode == ARM::BLX_noip || LastInstrOpcode == ARM::tBL ||
-             LastInstrOpcode == ARM::tBLXr ||
-             LastInstrOpcode == ARM::tBLXr_noip ||
-             LastInstrOpcode == ARM::tBLXi) {
+             LastInstrOpcode == ARM::tBLXi ||
+             ((LastInstrOpcode == ARM::tBLXr ||
+               LastInstrOpcode == ARM::tBLXr_noip) &&
+              ARM::tcGPRRegClass.contains(
+                  RepeatedSequenceLocs[0].back().getOperand(2).getReg()))) {
----------------
smithp35 wrote:

I agree that the `CantGuaranteeValueAcrossCall` will prevent r12 being used, as it must be live in order for the outlined sequence to tail call it.

The test case looks like it should work, but it seems like when the target is "thumbv8.1m.main-arm-none-eabi" then no matter what register is chosen then there is no instance of  `tTAILJMPr` if I change to thumbv7-m-unknown-none-eabihf and remove branch-target-enforcement I can see that r12 is not selected for a tail call.

As the `Can'tGuarantteValueAcrossCall` already exists I don't think you need to add another test.

https://github.com/llvm/llvm-project/pull/200684


More information about the llvm-commits mailing list