@@ -118,6 +118,7 @@ using namespace llvm;
118118#define DEBUG_TYPE "arm-isel"
119119
120120STATISTIC(NumTailCalls, "Number of tail calls");
121+ STATISTIC(NumOptimizedImms, "Number of times immediates were optimized");
121122STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt");
122123STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments");
123124STATISTIC(NumConstpoolPromoted,
@@ -20154,23 +20155,21 @@ static bool isLegalLogicalImmediate(unsigned Imm, const ARMSubtarget *Subtarget)
2015420155 return Imm <= 255;
2015520156}
2015620157
20157- static bool optimizeLogicalImm(SDValue Op, unsigned Size, unsigned Imm,
20158- const APInt &Demanded,
20158+ static bool optimizeLogicalImm(SDValue Op, unsigned Imm, const APInt &Demanded,
2015920159 TargetLowering::TargetLoweringOpt &TLO,
2016020160 unsigned NewOpc, const ARMSubtarget *Subtarget) {
20161- unsigned OldImm = Imm, NewImm, Enc;
20162- unsigned Mask = ~0U, OrigMask = Mask;
20163- bool Invert = false;
20161+ unsigned OldImm = Imm, NewImm;
20162+ unsigned Mask = ~0U;
2016420163
2016520164 // Return if the immediate is already all zeros, all ones, a bimm32.
20166- if (Imm == 0 || Imm == Mask || isLegalLogicalImmediate(Imm, Subtarget))
20165+ if (Imm == 0 || Imm == ~0U || isLegalLogicalImmediate(Imm, Subtarget))
2016720166 return false;
2016820167
2016920168 // bic/orn/eon
2017020169 if ((Op.getOpcode() == ISD::AND || (Subtarget->isThumb2() && Op.getOpcode() == ISD::OR)) && isLegalLogicalImmediate(~Imm, Subtarget))
2017120170 return false;
2017220171
20173- unsigned EltSize = Size ;
20172+ unsigned EltSize = 32 ;
2017420173 unsigned DemandedBits = Demanded.getZExtValue();
2017520174
2017620175 // Clear bits that are not demanded.
@@ -20220,7 +20219,7 @@ static bool optimizeLogicalImm(SDValue Op, unsigned Size, unsigned Imm,
2022020219 ++NumOptimizedImms;
2022120220
2022220221 // Replicate the element across the register width.
20223- while (EltSize < Size ) {
20222+ while (EltSize < 32 ) {
2022420223 NewImm |= NewImm << EltSize;
2022520224 EltSize *= 2;
2022620225 }
@@ -20237,15 +20236,14 @@ static bool optimizeLogicalImm(SDValue Op, unsigned Size, unsigned Imm,
2023720236
2023820237 // If the new constant immediate is all-zeros or all-ones, let the target
2023920238 // independent DAG combine optimize this node.
20240- if (NewImm == 0 || NewImm == OrigMask ) {
20239+ if (NewImm == 0 || NewImm == ~0U ) {
2024120240 New = TLO.DAG.getNode(Op.getOpcode(), DL, VT, Op.getOperand(0),
2024220241 TLO.DAG.getConstant(NewImm, DL, VT));
2024320242 // Otherwise, create a machine node so that target independent DAG combine
2024420243 // doesn't undo this optimization.
2024520244 } else {
20246- SDValue EncConst = TLO.DAG.getTargetConstant(NewImm, DL, VT);
20247- New = SDValue(
20248- TLO.DAG.getMachineNode(NewOpc, DL, VT, Op.getOperand(0), EncConst), 0);
20245+ // Temporarily disable this optimization to avoid crashes
20246+ return false;
2024920247 }
2025020248
2025120249 return TLO.CombineTo(Op, New);
@@ -20267,11 +20265,52 @@ bool ARMTargetLowering::targetShrinkDemandedConstant(
2026720265 return false;
2026820266
2026920267 assert(VT == MVT::i32 && "Unexpected integer type");
20270-
20268+
2027120269 // Exit early if we demand all bits.
20272- if (DemandedBits.popcount == 32)
20270+ if (DemandedBits.popcount() == 32)
20271+ return false;
20272+
20273+ // Make sure the RHS really is a constant.
20274+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20275+ if (!C)
2027320276 return false;
2027420277
20278+ unsigned Mask = C->getZExtValue();
20279+
20280+ // If thumb, check for uxth and uxtb masks.
20281+ if (Subtarget->isThumb1Only() && Op.getOpcode() == ISD::AND) {
20282+ unsigned Demanded = DemandedBits.getZExtValue();
20283+ unsigned ShrunkMask = Mask & Demanded;
20284+ unsigned ExpandedMask = Mask | ~Demanded;
20285+
20286+ // If the mask is all zeros, let the target-independent code replace the
20287+ // result with zero.
20288+ if (ShrunkMask == 0)
20289+ return false;
20290+
20291+ // If the mask is all ones, erase the AND. (Currently, the
20292+ // target-independent code won't do this, so we have to do it explicitly to
20293+ // avoid an infinite loop in obscure cases.)
20294+ if (ExpandedMask == ~0U)
20295+ return TLO.CombineTo(Op, Op.getOperand(0));
20296+ auto IsLegalMask = [ShrunkMask, ExpandedMask](unsigned Mask) -> bool {
20297+ return (ShrunkMask & Mask) == ShrunkMask && (~ExpandedMask & Mask) == 0;
20298+ };
20299+ auto UseMask = [Mask, Op, VT, &TLO](unsigned NewMask) -> bool {
20300+ if (NewMask == Mask)
20301+ return true;
20302+ SDLoc DL(Op);
20303+ SDValue NewC = TLO.DAG.getConstant(NewMask, DL, VT);
20304+ SDValue NewOp = TLO.DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), NewC);
20305+ return TLO.CombineTo(Op, NewOp);
20306+ };
20307+
20308+ if (IsLegalMask(0xFF))
20309+ return UseMask(0xFF);
20310+ if (IsLegalMask(0xFFFF))
20311+ return UseMask(0xFFFF);
20312+ }
20313+
2027520314 unsigned NewOpc;
2027620315 switch (Op.getOpcode()) {
2027720316 default:
@@ -20293,13 +20332,7 @@ bool ARMTargetLowering::targetShrinkDemandedConstant(
2029320332 break;
2029420333 }
2029520334
20296- // Make sure the RHS really is a constant.
20297- ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20298- if (!C)
20299- return false;
20300-
20301- unsigned Imm = C->getZExtValue();
20302- return optimizeLogicalImm(Op, Size, Imm, DemandedBits, TLO, NewOpc, Subtarget);
20335+ return optimizeLogicalImm(Op, Mask, DemandedBits, TLO, NewOpc, Subtarget);
2030320336}
2030420337
2030520338bool ARMTargetLowering::SimplifyDemandedBitsForTargetNode(
0 commit comments