Skip to content

Commit

Permalink
[AArch64] Turn BIC immediate creation into a DAG combine
Browse files Browse the repository at this point in the history
Switch BIC immediate creation for vector ANDs from custom lowering
to a DAG combine, which gives generic DAG combines a change to
apply first. In particular this avoids (and x, -1) being turned into
a (bic x, 0) instead of being eliminated entirely.

Differential Revision: https://reviews.llvm.org/D59187

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356299 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
nikic committed Mar 15, 2019
1 parent 4a413d3 commit 6185a3e
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 440 deletions.
87 changes: 44 additions & 43 deletions lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,

// We combine OR nodes for bitfield operations.
setTargetDAGCombine(ISD::OR);
// Try to create BICs for vector ANDs.
setTargetDAGCombine(ISD::AND);

// Vector add and sub nodes may conceal a high-half opportunity.
// Also, try to fold ADD into CSINC/CSINV..
Expand Down Expand Up @@ -799,7 +801,6 @@ void AArch64TargetLowering::addTypeForNEON(MVT VT, MVT PromotedBitwiseVT) {
setOperationAction(ISD::SRA, VT, Custom);
setOperationAction(ISD::SRL, VT, Custom);
setOperationAction(ISD::SHL, VT, Custom);
setOperationAction(ISD::AND, VT, Custom);
setOperationAction(ISD::OR, VT, Custom);
setOperationAction(ISD::SETCC, VT, Custom);
setOperationAction(ISD::CONCAT_VECTORS, VT, Legal);
Expand Down Expand Up @@ -2940,8 +2941,6 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerCTPOP(Op, DAG);
case ISD::FCOPYSIGN:
return LowerFCOPYSIGN(Op, DAG);
case ISD::AND:
return LowerVectorAND(Op, DAG);
case ISD::OR:
return LowerVectorOR(Op, DAG);
case ISD::XOR:
Expand Down Expand Up @@ -6922,46 +6921,6 @@ static SDValue tryAdvSIMDModImmFP(unsigned NewOp, SDValue Op, SelectionDAG &DAG,
return SDValue();
}

SDValue AArch64TargetLowering::LowerVectorAND(SDValue Op,
SelectionDAG &DAG) const {
SDValue LHS = Op.getOperand(0);
EVT VT = Op.getValueType();

BuildVectorSDNode *BVN =
dyn_cast<BuildVectorSDNode>(Op.getOperand(1).getNode());
if (!BVN) {
// AND commutes, so try swapping the operands.
LHS = Op.getOperand(1);
BVN = dyn_cast<BuildVectorSDNode>(Op.getOperand(0).getNode());
}
if (!BVN)
return Op;

APInt DefBits(VT.getSizeInBits(), 0);
APInt UndefBits(VT.getSizeInBits(), 0);
if (resolveBuildVector(BVN, DefBits, UndefBits)) {
SDValue NewOp;

// We only have BIC vector immediate instruction, which is and-not.
DefBits = ~DefBits;
if ((NewOp = tryAdvSIMDModImm32(AArch64ISD::BICi, Op, DAG,
DefBits, &LHS)) ||
(NewOp = tryAdvSIMDModImm16(AArch64ISD::BICi, Op, DAG,
DefBits, &LHS)))
return NewOp;

UndefBits = ~UndefBits;
if ((NewOp = tryAdvSIMDModImm32(AArch64ISD::BICi, Op, DAG,
UndefBits, &LHS)) ||
(NewOp = tryAdvSIMDModImm16(AArch64ISD::BICi, Op, DAG,
UndefBits, &LHS)))
return NewOp;
}

// We can always fall back to a non-immediate AND.
return Op;
}

// Specialized code to quickly find if PotentialBVec is a BuildVector that
// consists of only the same constant int value, returned in reference arg
// ConstVal
Expand Down Expand Up @@ -9433,6 +9392,46 @@ static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
return SDValue();
}

static SDValue performANDCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI) {
SelectionDAG &DAG = DCI.DAG;
SDValue LHS = N->getOperand(0);
EVT VT = N->getValueType(0);
if (!VT.isVector() || !DAG.getTargetLoweringInfo().isTypeLegal(VT))
return SDValue();

BuildVectorSDNode *BVN =
dyn_cast<BuildVectorSDNode>(N->getOperand(1).getNode());
if (!BVN)
return SDValue();

// AND does not accept an immediate, so check if we can use a BIC immediate
// instruction instead. We do this here instead of using a (and x, (mvni imm))
// pattern in isel, because some immediates may be lowered to the preferred
// (and x, (movi imm)) form, even though an mvni representation also exists.
APInt DefBits(VT.getSizeInBits(), 0);
APInt UndefBits(VT.getSizeInBits(), 0);
if (resolveBuildVector(BVN, DefBits, UndefBits)) {
SDValue NewOp;

DefBits = ~DefBits;
if ((NewOp = tryAdvSIMDModImm32(AArch64ISD::BICi, SDValue(N, 0), DAG,
DefBits, &LHS)) ||
(NewOp = tryAdvSIMDModImm16(AArch64ISD::BICi, SDValue(N, 0), DAG,
DefBits, &LHS)))
return NewOp;

UndefBits = ~UndefBits;
if ((NewOp = tryAdvSIMDModImm32(AArch64ISD::BICi, SDValue(N, 0), DAG,
UndefBits, &LHS)) ||
(NewOp = tryAdvSIMDModImm16(AArch64ISD::BICi, SDValue(N, 0), DAG,
UndefBits, &LHS)))
return NewOp;
}

return SDValue();
}

static SDValue performSRLCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI) {
SelectionDAG &DAG = DCI.DAG;
Expand Down Expand Up @@ -11283,6 +11282,8 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
return performFDivCombine(N, DAG, DCI, Subtarget);
case ISD::OR:
return performORCombine(N, DCI, Subtarget);
case ISD::AND:
return performANDCombine(N, DCI);
case ISD::SRL:
return performSRLCombine(N, DCI);
case ISD::INTRINSIC_WO_CHAIN:
Expand Down
1 change: 0 additions & 1 deletion lib/Target/AArch64/AArch64ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,6 @@ class AArch64TargetLowering : public TargetLowering {
SDValue LowerVectorFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVectorAND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVectorOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const;
Expand Down
13 changes: 6 additions & 7 deletions test/CodeGen/AArch64/sadd_sat.ll
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,14 @@ define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
; CHECK-NEXT: add v2.4s, v0.4s, v1.4s
; CHECK-NEXT: cmge v1.4s, v1.4s, #0
; CHECK-NEXT: cmge v0.4s, v0.4s, #0
; CHECK-NEXT: cmge v4.4s, v2.4s, #0
; CHECK-NEXT: movi v3.4s, #128, lsl #24
; CHECK-NEXT: cmeq v1.4s, v0.4s, v1.4s
; CHECK-NEXT: cmeq v0.4s, v0.4s, v4.4s
; CHECK-NEXT: cmge v5.4s, v2.4s, #0
; CHECK-NEXT: cmlt v4.4s, v2.4s, #0
; CHECK-NEXT: bic v3.16b, v3.16b, v4.16b
; CHECK-NEXT: bic v4.4s, #128, lsl #24
; CHECK-NEXT: cmeq v1.4s, v0.4s, v1.4s
; CHECK-NEXT: cmeq v0.4s, v0.4s, v5.4s
; CHECK-NEXT: mvni v3.4s, #128, lsl #24
; CHECK-NEXT: mvn v5.16b, v4.16b
; CHECK-NEXT: mvn v0.16b, v0.16b
; CHECK-NEXT: orr v3.16b, v4.16b, v3.16b
; CHECK-NEXT: bsl v3.16b, v4.16b, v5.16b
; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
; CHECK-NEXT: bsl v0.16b, v3.16b, v2.16b
; CHECK-NEXT: ret
Expand Down
Loading

0 comments on commit 6185a3e

Please sign in to comment.