[llvm] 816d3f2 - [ARM] Allow predicated `subs pc, lr, #imm` in Thumb2 (#205751)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 01:13:47 PDT 2026


Author: Chris Copeland
Date: 2026-06-30T09:13:42+01:00
New Revision: 816d3f25995595aa34ee3b65811dd5a5eab077e6

URL: https://github.com/llvm/llvm-project/commit/816d3f25995595aa34ee3b65811dd5a5eab077e6
DIFF: https://github.com/llvm/llvm-project/commit/816d3f25995595aa34ee3b65811dd5a5eab077e6.diff

LOG: [ARM] Allow predicated `subs pc, lr, #imm` in Thumb2 (#205751)

ARMAsmParser has a special case for this instruction that used the
instruction name unmodified, but this would include the condition code,
so if the instruction has one, the tblgen entry doesn't match. The
condition code is already added as a separate operand.

Check for `CarrySetting` so that the special case does not falsely match
on `sub pc, lr, #imm`, which is not valid in Thumb2.

Added: 
    

Modified: 
    llvm/docs/ReleaseNotes.md
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/test/MC/ARM/basic-thumb2-instructions.s
    llvm/test/MC/ARM/thumb2-diagnostics.s

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 143c6b4113e78..e82cee3cafa01 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -208,6 +208,7 @@ Makes programs 10x faster by doing Special New Thing.
 * The `r14` register can now be used as an alias for the link register `lr`
   in inline assembly. Clang always canonicalizes the name to `lr`, but other
   frontends may not.
+* `subs pc, lr, #imm` can now be predicated in Thumb2.
 
 ### Changes to the AVR Backend
 

diff  --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 1cac96a744733..bd90afd9e77d0 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -7468,9 +7468,9 @@ bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
   // FIXME: As said above, this is all a pretty gross hack.  This instruction
   // does not fit with other "subs" and tblgen.
   // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
-  // so the Mnemonic is the original name "subs" and delete the predicate
-  // operand so it will match the table entry.
-  if (isThumbTwo() && Mnemonic == "sub" &&
+  // so the Mnemonic is "subs" and delete the CCOut operand so it will match
+  // the table entry.
+  if (isThumbTwo() && Mnemonic == "sub" && CarrySetting &&
       Operands.size() == MnemonicOpsEndInd + 3 &&
       static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isReg() &&
       static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).getReg() ==
@@ -7479,7 +7479,7 @@ bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
       static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).getReg() ==
           ARM::LR &&
       static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]).isImm()) {
-    Operands.front() = ARMOperand::CreateToken(Name, NameLoc, *this);
+    Operands.front() = ARMOperand::CreateToken("subs", NameLoc, *this);
     removeCCOut(Operands, MnemonicOpsEndInd);
   }
   return false;

diff  --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s
index 98768b5d6a176..61ebb19aa05e6 100644
--- a/llvm/test/MC/ARM/basic-thumb2-instructions.s
+++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s
@@ -4168,3 +4168,9 @@ adds sp, #-4096
 @ rdar://14214063
          subs pc, lr, #4
 @ CHECK: subs pc, lr, #4                @ encoding: [0xde,0xf3,0x04,0x8f]
+
+@ SUBS PC, LR, #imm is also predicable inside an IT block.
+         it ne
+         subsne pc, lr, #2
+@ CHECK: it ne                          @ encoding: [0x18,0xbf]
+@ CHECK: subsne pc, lr, #2              @ encoding: [0xde,0xf3,0x02,0x8f]

diff  --git a/llvm/test/MC/ARM/thumb2-diagnostics.s b/llvm/test/MC/ARM/thumb2-diagnostics.s
index afb12ce430981..70878a13990e3 100644
--- a/llvm/test/MC/ARM/thumb2-diagnostics.s
+++ b/llvm/test/MC/ARM/thumb2-diagnostics.s
@@ -195,3 +195,8 @@ foo2:
         @ v8 allows rn = sp
 @ CHECK-ERRORS-V7: error: instruction variant requires ARMv8 or later
         @ rn=pc is allowed so not included here
+
+        @ "sub pc, lr, #imm" (without 's') is not a Thumb2 instruction
+        sub pc, lr, #4
+@ CHECK-ERRORS-V7: error: operand must be a register in range [r0, r12] or r14
+@ CHECK-ERRORS-V8: error: operand must be a register in range [r0, r14]


        


More information about the llvm-commits mailing list