[llvm] [PPC] Remove the long-standing workaround for the "ANDI glue bug" in the PowerPC backend and the associated dead PPCISD opcodes. (PR #185546)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 07:13:09 PDT 2026


https://github.com/SiliconA-Z updated https://github.com/llvm/llvm-project/pull/185546

>From deba0b0463cc8db2eb620ffae14e5f652586edcd Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 9 Mar 2026 15:04:31 -0400
Subject: [PATCH] [PPC] Remove the long-standing workaround for the "ANDI glue
 bug" in the PowerPC backend and the associated dead PPCISD opcodes.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

It's dead and the glue code implicitly defines CR0.

Truncation of i32/i64 to i1 is unchanged: it is still implemented via the tablegen pseudos and the custom inserter that emits ANDI_rec/ANDI8_rec and COPY from CR0. The ANDI instructions already have `Defs = [CR0]`, so the ANDI→COPY ordering is preserved by the existing def/use of CR0.
---
 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp   | 28 -------------------
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   | 20 ++-----------
 llvm/lib/Target/PowerPC/PPCISelLowering.h     |  1 -
 .../Target/PowerPC/PPCSelectionDAGInfo.cpp    |  4 ---
 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h |  7 -----
 5 files changed, 2 insertions(+), 58 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index c34f4809278ae..0fe85bbd71653 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -88,10 +88,6 @@ STATISTIC(OmittedForNonExtendUses,
 STATISTIC(NumP9Setb,
           "Number of compares lowered to setb.");
 
-// FIXME: Remove this once the bug has been fixed!
-cl::opt<bool> ANDIGlueBug("expose-ppc-andi-glue-bug",
-cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden);
-
 static cl::opt<bool>
     UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true),
                        cl::desc("use aggressive ppc isel for bit permutations"),
@@ -5826,30 +5822,6 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
     }
     break;
   }
-  // FIXME: Remove this once the ANDI glue bug is fixed:
-  case PPCISD::ANDI_rec_1_EQ_BIT:
-  case PPCISD::ANDI_rec_1_GT_BIT: {
-    if (!ANDIGlueBug)
-      break;
-
-    EVT InVT = N->getOperand(0).getValueType();
-    assert((InVT == MVT::i64 || InVT == MVT::i32) &&
-           "Invalid input type for ANDI_rec_1_EQ_BIT");
-
-    unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
-    SDValue AndI(CurDAG->getMachineNode(Opcode, dl, InVT, MVT::Glue,
-                                        N->getOperand(0),
-                                        CurDAG->getTargetConstant(1, dl, InVT)),
-                 0);
-    SDValue CR0Reg = CurDAG->getRegister(PPC::CR0, MVT::i32);
-    SDValue SRIdxVal = CurDAG->getTargetConstant(
-        N->getOpcode() == PPCISD::ANDI_rec_1_EQ_BIT ? PPC::sub_eq : PPC::sub_gt,
-        dl, MVT::i32);
-
-    CurDAG->SelectNodeTo(N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
-                         SRIdxVal, SDValue(AndI.getNode(), 1) /* glue */);
-    return;
-  }
   case ISD::SELECT_CC: {
     ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
     EVT PtrVT =
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 84d26448a7f4f..0d98789690e03 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -169,9 +169,6 @@ static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl);
 // slightly under 32KB.
 constexpr uint64_t AIXSmallTlsPolicySizeLimit = 32751;
 
-// FIXME: Remove this once the bug has been fixed!
-extern cl::opt<bool> ANDIGlueBug;
-
 PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
                                      const PPCSubtarget &STI)
     : TargetLowering(TM, STI), Subtarget(STI) {
@@ -311,10 +308,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
     setOperationAction(ISD::LOAD, MVT::i1, Custom);
     setOperationAction(ISD::STORE, MVT::i1, Custom);
 
-    // FIXME: Remove this once the ANDI glue bug is fixed:
-    if (ANDIGlueBug)
-      setOperationAction(ISD::TRUNCATE, MVT::i1, Custom);
-
     for (MVT VT : MVT::integer_valuetypes()) {
       setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
       setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);
@@ -8039,15 +8032,6 @@ SDValue PPCTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getTruncStore(Chain, dl, Value, BasePtr, MVT::i8, MMO);
 }
 
-// FIXME: Remove this once the ANDI glue bug is fixed:
-SDValue PPCTargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
-  assert(Op.getValueType() == MVT::i1 &&
-         "Custom lowering only for i1 results");
-
-  SDLoc DL(Op);
-  return DAG.getNode(PPCISD::ANDI_rec_1_GT_BIT, DL, MVT::i1, Op.getOperand(0));
-}
-
 SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
                                                SelectionDAG &DAG) const {
 
@@ -12692,8 +12676,8 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   case ISD::EH_SJLJ_LONGJMP:    return lowerEH_SJLJ_LONGJMP(Op, DAG);
 
   case ISD::LOAD:               return LowerLOAD(Op, DAG);
-  case ISD::STORE:              return LowerSTORE(Op, DAG);
-  case ISD::TRUNCATE:           return LowerTRUNCATE(Op, DAG);
+  case ISD::STORE:
+    return LowerSTORE(Op, DAG);
   case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
   case ISD::STRICT_FP_TO_UINT:
   case ISD::STRICT_FP_TO_SINT:
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 4e816790b3f02..5fa8b0012a14b 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -719,7 +719,6 @@ namespace llvm {
     SDValue LowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
-    SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
                            const SDLoc &dl) const;
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
index d0c685d95d2b5..f774024b786c2 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
@@ -29,10 +29,6 @@ const char *PPCSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
     return "PPCISD::READ_TIME_BASE";
   case PPCISD::MFOCRF:
     return "PPCISD::MFOCRF";
-  case PPCISD::ANDI_rec_1_EQ_BIT:
-    return "PPCISD::ANDI_rec_1_EQ_BIT";
-  case PPCISD::ANDI_rec_1_GT_BIT:
-    return "PPCISD::ANDI_rec_1_GT_BIT";
   case PPCISD::BDNZ:
     return "PPCISD::BDNZ";
   case PPCISD::BDZ:
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
index 17d544a8d558f..97a94cb81a830 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
@@ -32,13 +32,6 @@ enum NodeType : unsigned {
   /// resultant GPR.  Bits corresponding to other CR regs are undefined.
   MFOCRF,
 
-  // FIXME: Remove these once the ANDI glue bug is fixed:
-  /// i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the
-  /// eq or gt bit of CR0 after executing andi. x, 1. This is used to
-  /// implement truncation of i32 or i64 to i1.
-  ANDI_rec_1_EQ_BIT,
-  ANDI_rec_1_GT_BIT,
-
   // READ_TIME_BASE - A read of the 64-bit time-base register on a 32-bit
   // target (returns (Lo, Hi)). It takes a chain operand.
   READ_TIME_BASE,



More information about the llvm-commits mailing list