Skip to content

Commit 3bfb4b4

Browse files
committed
[ARM] Port LowerSELECTWithCmpZero to ARM
1 parent 779868d commit 3bfb4b4

File tree

4 files changed

+295
-208
lines changed

4 files changed

+295
-208
lines changed

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5143,6 +5143,113 @@ SDValue ARMTargetLowering::LowerUnsignedALUO(SDValue Op,
51435143
return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
51445144
}
51455145

5146+
// Lower various (select (icmp CmpVal, 0), LHS, RHS) custom patterns.
5147+
static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
5148+
ISD::CondCode CC, const SDLoc &DL,
5149+
SelectionDAG &DAG,
5150+
const ARMSubtarget &Subtarget) {
5151+
EVT CmpVT = CmpVal.getValueType();
5152+
EVT VT = LHS.getValueType();
5153+
if (!CmpVT.isScalarInteger() || !VT.isScalarInteger())
5154+
return SDValue();
5155+
5156+
if (CC == ISD::SETEQ && CmpVal.getOpcode() == ISD::AND &&
5157+
isOneConstant(CmpVal.getOperand(1))) {
5158+
auto SplatLSB = [&](EVT SplatVT) {
5159+
// we need mask of all zeros or ones with same size of the other
5160+
// operands.
5161+
SDValue Neg = CmpVal;
5162+
if (CmpVT.bitsGT(SplatVT))
5163+
Neg = DAG.getNode(ISD::TRUNCATE, DL, SplatVT, CmpVal);
5164+
else if (CmpVT.bitsLT(SplatVT))
5165+
Neg = DAG.getNode(
5166+
ISD::AND, DL, SplatVT,
5167+
DAG.getNode(ISD::ANY_EXTEND, DL, SplatVT, CmpVal.getOperand(0)),
5168+
DAG.getConstant(1, DL, SplatVT));
5169+
return DAG.getNegative(Neg, DL, SplatVT); // -(and (x, 0x1))
5170+
};
5171+
5172+
// SELECT (AND(X,1) == 0), 0, -1 -> NEG(AND(X,1))
5173+
if (isNullConstant(LHS) && isAllOnesConstant(RHS))
5174+
return SplatLSB(VT);
5175+
5176+
// SELECT (AND(X,1) == 0), C1, C2 -> XOR(C1,AND(NEG(AND(X,1)),XOR(C1,C2))
5177+
if (Subtarget.isThumb1Only() && isa<ConstantSDNode>(LHS) &&
5178+
isa<ConstantSDNode>(RHS)) {
5179+
SDValue Mask = SplatLSB(VT);
5180+
SDValue Diff = DAG.getNode(ISD::XOR, DL, VT, LHS, RHS);
5181+
SDValue Flip = DAG.getNode(ISD::AND, DL, VT, Mask, Diff);
5182+
return DAG.getNode(ISD::XOR, DL, VT, LHS, Flip);
5183+
}
5184+
5185+
SDValue Src1, Src2;
5186+
auto isIdentityPatternZero = [&]() {
5187+
switch (RHS.getOpcode()) {
5188+
default:
5189+
break;
5190+
case ISD::OR:
5191+
case ISD::XOR:
5192+
case ISD::ADD:
5193+
if (RHS.getOperand(0) == LHS || RHS.getOperand(1) == LHS) {
5194+
Src1 = RHS.getOperand(RHS.getOperand(0) == LHS ? 1 : 0);
5195+
Src2 = LHS;
5196+
return true;
5197+
}
5198+
break;
5199+
case ISD::SHL:
5200+
case ISD::SRA:
5201+
case ISD::SRL:
5202+
case ISD::SUB:
5203+
if (RHS.getOperand(0) == LHS) {
5204+
Src1 = RHS.getOperand(1);
5205+
Src2 = LHS;
5206+
return true;
5207+
}
5208+
break;
5209+
}
5210+
return false;
5211+
};
5212+
5213+
auto isIdentityPatternOnes = [&]() {
5214+
switch (LHS.getOpcode()) {
5215+
default:
5216+
break;
5217+
case ISD::AND:
5218+
if (LHS.getOperand(0) == RHS || LHS.getOperand(1) == RHS) {
5219+
Src1 = LHS.getOperand(LHS.getOperand(0) == RHS ? 1 : 0);
5220+
Src2 = RHS;
5221+
return true;
5222+
}
5223+
break;
5224+
}
5225+
return false;
5226+
};
5227+
5228+
// Convert 'identity' patterns (iff X is 0 or 1):
5229+
// SELECT (AND(X,1) == 0), Y, (OR Y, Z) -> (OR Y, (AND NEG(AND(X,1)), Z))
5230+
// SELECT (AND(X,1) == 0), Y, (XOR Y, Z) -> (XOR Y, (AND NEG(AND(X,1)), Z))
5231+
// SELECT (AND(X,1) == 0), Y, (ADD Y, Z) -> (ADD Y, (AND NEG(AND(X,1)), Z))
5232+
// SELECT (AND(X,1) == 0), Y, (SUB Y, Z) -> (SUB Y, (AND NEG(AND(X,1)), Z))
5233+
// SELECT (AND(X,1) == 0), Y, (SHL Y, Z) -> (SHL Y, (AND NEG(AND(X,1)), Z))
5234+
// SELECT (AND(X,1) == 0), Y, (SRA Y, Z) -> (SRA Y, (AND NEG(AND(X,1)), Z))
5235+
// SELECT (AND(X,1) == 0), Y, (SRL Y, Z) -> (SRL Y, (AND NEG(AND(X,1)), Z))
5236+
if (Subtarget.isThumb1Only() && isIdentityPatternZero()) {
5237+
SDValue Mask = SplatLSB(Src1.getValueType());
5238+
SDValue And = DAG.getNode(ISD::AND, DL, Src1.getValueType(), Mask,
5239+
Src1); // Mask & z
5240+
return DAG.getNode(RHS.getOpcode(), DL, VT, Src2, And); // y Op And
5241+
}
5242+
// SELECT (AND(X,1) == 0), (AND Y, Z), Y -> (AND Y, (OR NEG(AND(X, 1)), Z))
5243+
if (Subtarget.isThumb1Only() && isIdentityPatternOnes()) {
5244+
SDValue Mask = SplatLSB(VT);
5245+
SDValue Or = DAG.getNode(ISD::OR, DL, VT, Mask, Src1); // Mask | z
5246+
return DAG.getNode(LHS.getOpcode(), DL, VT, Src2, Or); // y Op Or
5247+
}
5248+
}
5249+
5250+
return SDValue();
5251+
}
5252+
51465253
static SDValue LowerADDSUBSAT(SDValue Op, SelectionDAG &DAG,
51475254
const ARMSubtarget *Subtarget) {
51485255
EVT VT = Op.getValueType();
@@ -5521,7 +5628,6 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
55215628
ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
55225629
ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
55235630
if (Op.getValueType().isInteger()) {
5524-
55255631
// Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
55265632
// (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
55275633
// (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
@@ -5539,6 +5645,11 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
55395645

55405646
return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
55415647
}
5648+
if (RHSC && RHSC->isZero()) {
5649+
if (SDValue R = LowerSELECTWithCmpZero(LHS, TrueVal, FalseVal, CC, dl,
5650+
DAG, *Subtarget))
5651+
return R;
5652+
}
55425653
}
55435654

55445655
if (Subtarget->hasV8_1MMainlineOps() && CFVal && CTVal &&

llvm/test/CodeGen/ARM/arm-and-tst-peephole.ll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,10 @@ define i32 @test_tst_assessment(i32 %a, i32 %b) {
334334
;
335335
; THUMB-LABEL: test_tst_assessment:
336336
; THUMB: @ %bb.0:
337-
; THUMB-NEXT: movs r2, r0
338-
; THUMB-NEXT: movs r0, #1
337+
; THUMB-NEXT: movs r2, #1
338+
; THUMB-NEXT: ands r1, r2
339339
; THUMB-NEXT: ands r0, r2
340-
; THUMB-NEXT: lsls r1, r1, #31
341-
; THUMB-NEXT: beq .LBB2_2
342-
; THUMB-NEXT: @ %bb.1:
343-
; THUMB-NEXT: subs r0, r0, #1
344-
; THUMB-NEXT: .LBB2_2:
340+
; THUMB-NEXT: subs r0, r0, r1
345341
; THUMB-NEXT: bx lr
346342
;
347343
; T2-LABEL: test_tst_assessment:

0 commit comments

Comments
 (0)