[llvm] r259387 - AArch64: Implement missed conditional compare sequences.
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 6 14:29:37 PDT 2016
Hi Balaram,
Sorry for the late reply, but I am seeing this commit is causing problem internally.
> On Feb 1, 2016, at 11:13 AM, Balaram Makam via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Author: bmakam
> Date: Mon Feb 1 13:13:07 2016
> New Revision: 259387
>
> URL: http://llvm.org/viewvc/llvm-project?rev=259387&view=rev
> Log:
> AArch64: Implement missed conditional compare sequences.
>
> Summary:
> This is an extension to the existing implementation of r242436 which
> restricts to only select inputs. This version fixes missed opportunities
> in pr26084 by attempting to lower conditional compare sequences of
> and/or trees with setcc leafs. This will additionaly handle the case
> when a tree with select input is not a conjunction-disjunction tree
> but some of the sub trees are conjunction-disjunction trees.
>
> Reviewers: jmolloy, t.p.northover, mcrosier, MatzeB
>
> Subscribers: mcrosier, llvm-commits, junbuml, haicheng, mssimpso, gberry
>
> Differential Revision: http://reviews.llvm.org/D16291
>
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
> llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h
> llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=259387&r1=259386&r2=259387&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Feb 1 13:13:07 2016
> @@ -1721,7 +1721,7 @@ SDValue DAGCombiner::visitADD(SDNode *N)
> return SDValue(N, 0);
>
> // fold (a+b) -> (a|b) iff a and b share no bits.
> - if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
> + if ((!LegalOperations || TLI.isOperationLegalOrCustom(ISD::OR, VT)) &&
This is wrong. Custom does not imply that the operation is Legal!
You said in the review that without custom, one of the lit test case was failing. I believe you can fix that by making the Custom lowering as part of the combine process (PerformDAGCombine.)
Anyhow, this line is generally not correct.
Cheers,
-Quentin
> VT.isInteger() && !VT.isVector() && DAG.haveNoCommonBitsSet(N0, N1))
> return DAG.getNode(ISD::OR, SDLoc(N), VT, N0, N1);
>
> @@ -6363,7 +6363,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SD
> isa<LoadSDNode>(N0.getOperand(0)) &&
> N0.getOperand(1).getOpcode() == ISD::Constant &&
> TLI.isLoadExtLegal(ISD::ZEXTLOAD, VT, N0.getValueType()) &&
> - (!LegalOperations && TLI.isOperationLegal(N0.getOpcode(), VT))) {
> + (!LegalOperations && TLI.isOperationLegalOrCustom(N0.getOpcode(), VT))) {
> LoadSDNode *LN0 = cast<LoadSDNode>(N0.getOperand(0));
> if (LN0->getExtensionType() != ISD::SEXTLOAD && LN0->isUnindexed()) {
> bool DoXform = true;
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=259387&r1=259386&r2=259387&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Mon Feb 1 13:13:07 2016
> @@ -144,6 +144,16 @@ AArch64TargetLowering::AArch64TargetLowe
> setOperationAction(ISD::XOR, MVT::i32, Custom);
> setOperationAction(ISD::XOR, MVT::i64, Custom);
>
> + // Custom lowering hooks are needed for OR
> + // to fold it into CCMP.
> + setOperationAction(ISD::OR, MVT::i32, Custom);
> + setOperationAction(ISD::OR, MVT::i64, Custom);
> +
> + // Custom lowering hooks are needed for AND
> + // to fold it into CCMP.
> + setOperationAction(ISD::AND, MVT::i32, Custom);
> + setOperationAction(ISD::AND, MVT::i64, Custom);
> +
> // Virtually no operation on f128 is legal, but LLVM can't expand them when
> // there's a valid register class, so we need custom operations in most cases.
> setOperationAction(ISD::FABS, MVT::f128, Expand);
> @@ -1597,6 +1607,27 @@ static SDValue getAArch64Cmp(SDValue LHS
> return Cmp;
> }
>
> +// Attempt to form conditional compare sequences for and/or trees
> +// with setcc leafs.
> +static SDValue tryLowerToAArch64Cmp(SDValue Op, SelectionDAG &DAG) {
> + SDValue LHS = Op.getOperand(0);
> + SDValue RHS = Op.getOperand(1);
> + if ((LHS.getOpcode() != ISD::SETCC) || (RHS.getOpcode() != ISD::SETCC))
> + return Op;
> +
> + bool CanNegate;
> + if (!isConjunctionDisjunctionTree(Op, CanNegate))
> + return SDValue();
> +
> + EVT VT = Op.getValueType();
> + SDLoc DL(Op);
> + SDValue TVal = DAG.getConstant(1, DL, VT);
> + SDValue FVal = DAG.getConstant(0, DL, VT);
> + SDValue CCVal;
> + SDValue Cmp = getAArch64Cmp(Op, FVal, ISD::SETEQ, CCVal, DAG, DL);
> + return DAG.getNode(AArch64ISD::CSEL, DL, VT, FVal, TVal, CCVal, Cmp);
> +}
> +
> static std::pair<SDValue, SDValue>
> getAArch64XALUOOp(AArch64CC::CondCode &CC, SDValue Op, SelectionDAG &DAG) {
> assert((Op.getValueType() == MVT::i32 || Op.getValueType() == MVT::i64) &&
> @@ -1718,6 +1749,18 @@ SDValue AArch64TargetLowering::LowerF128
> return makeLibCall(DAG, Call, MVT::f128, Ops, false, SDLoc(Op)).first;
> }
>
> +SDValue AArch64TargetLowering::LowerAND(SDValue Op, SelectionDAG &DAG) const {
> + if (Op.getValueType().isVector())
> + return LowerVectorAND(Op, DAG);
> + return tryLowerToAArch64Cmp(Op, DAG);
> +}
> +
> +SDValue AArch64TargetLowering::LowerOR(SDValue Op, SelectionDAG &DAG) const {
> + if (Op.getValueType().isVector())
> + return LowerVectorOR(Op, DAG);
> + return tryLowerToAArch64Cmp(Op, DAG);
> +}
> +
> static SDValue LowerXOR(SDValue Op, SelectionDAG &DAG) {
> SDValue Sel = Op.getOperand(0);
> SDValue Other = Op.getOperand(1);
> @@ -2372,9 +2415,9 @@ SDValue AArch64TargetLowering::LowerOper
> case ISD::FCOPYSIGN:
> return LowerFCOPYSIGN(Op, DAG);
> case ISD::AND:
> - return LowerVectorAND(Op, DAG);
> + return LowerAND(Op, DAG);
> case ISD::OR:
> - return LowerVectorOR(Op, DAG);
> + return LowerOR(Op, DAG);
> case ISD::XOR:
> return LowerXOR(Op, DAG);
> case ISD::PREFETCH:
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=259387&r1=259386&r2=259387&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h Mon Feb 1 13:13:07 2016
> @@ -488,6 +488,8 @@ private:
> SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerF128Call(SDValue Op, SelectionDAG &DAG,
> RTLIB::Libcall Call) const;
> + SDValue LowerAND(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerOR(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
>
> Modified: llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll?rev=259387&r1=259386&r2=259387&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll (original)
> +++ llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll Mon Feb 1 13:13:07 2016
> @@ -371,21 +371,76 @@ define i32 @select_andor(i32 %v1, i32 %v
> ret i32 %sel
> }
>
> -; CHECK-LABEL: select_noccmp1
> -define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
> -; CHECK: cmp x0, #0
> -; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt
> -; CHECK-NEXT: cmp x0, #13
> -; CHECK-NOT: ccmp
> +; CHECK-LABEL: single_noselect
> +define i32 @single_noselect(i32 %A, i32 %B) #0 {
> +; CHECK: cmp w1, #1
> +; CHECK-NEXT: ccmp w0, #1, #8, ge
> +; CHECK-NEXT: cset w0, lt
> +; CHECK-NEXT: ret
> + %notlhs = icmp slt i32 %A, 1
> + %notrhs = icmp slt i32 %B, 1
> + %lnot = or i1 %notlhs, %notrhs
> + %conv = zext i1 %lnot to i32
> + ret i32 %conv
> +}
> +
> +; CHECK-LABEL: single_and_ext
> +define i32 @single_and_ext(i32 %A, i32 %B, i32 %C) #0 {
> +; CHECK: cmp w1, #2
> +; CHECK-NEXT: ccmp w0, #4, #0, lt
> +; CHECK-NEXT: cinc w0, w2, lt
> +; CHECK-NEXT: ret
> + %cmp = icmp slt i32 %A, 4
> + %cmp1 = icmp slt i32 %B, 2
> + %and1 = and i1 %cmp, %cmp1
> + %conv = zext i1 %and1 to i32
> + %add = add nsw i32 %conv, %C
> + ret i32 %add
> +}
> +
> +; CHECK-LABEL: single_noselect_phi
> +define i32 @single_noselect_phi(i32 %A, i32 %B, i32 %C) #0 {
> +; CHECK: cmp w1, #0
> +; CHECK-NEXT: ccmp w0, #0, #4, gt
> ; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt
> -; CHECK-NEXT: cmp x2, #2
> +; CHECK-NEXT: cmp w1, #2
> +; CHECK-NEXT: ccmp w0, #4, #8, ge
> ; CHECK-NEXT: cset [[REG2:w[0-9]+]], lt
> +; CHECK-NEXT: cmp w2, #0
> +; CHECK-NEXT: csel w0, [[REG1]], [[REG2]], eq
> +; CHECK-NEXT: ret
> +entry:
> + %tobool = icmp eq i32 %C, 0
> + br i1 %tobool, label %if.else, label %if.then
> +
> +if.then: ; preds = %entry
> + %cmp = icmp slt i32 %A, 4
> + %cmp1 = icmp slt i32 %B, 2
> + %0 = or i1 %cmp, %cmp1
> + br label %if.end
> +
> +if.else: ; preds = %entry
> + %cmp2 = icmp sgt i32 %A, 0
> + %cmp3 = icmp sgt i32 %B, 0
> + %1 = and i1 %cmp2, %cmp3
> + br label %if.end
> +
> +if.end: ; preds = %if.else, %if.then
> + %b.0.in = phi i1 [ %0, %if.then ], [ %1, %if.else ]
> + %conv = zext i1 %b.0.in to i32
> + ret i32 %conv
> +}
> +
> +; CHECK-LABEL: select_noccmp1
> +define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
> +; CHECK: cmp x0, #13
> +; CHECK-NEXT: ccmp x0, #0, #0, gt
> +; CHECK-NEXT: cset [[REG1:w[0-9]+]], lt
> ; CHECK-NEXT: cmp x2, #4
> -; CHECK-NEXT: cset [[REG3:w[0-9]+]], gt
> -; CHECK-NEXT: and [[REG4:w[0-9]+]], [[REG0]], [[REG1]]
> -; CHECK-NEXT: and [[REG5:w[0-9]+]], [[REG2]], [[REG3]]
> -; CHECK-NEXT: orr [[REG6:w[0-9]+]], [[REG4]], [[REG5]]
> -; CHECK-NEXT: cmp [[REG6]], #0
> +; CHECK-NEXT: ccmp x2, #2, #0, gt
> +; CHECK-NEXT: cset [[REG2:w[0-9]+]], lt
> +; CHECK-NEXT: orr [[REG3:w[0-9]+]], [[REG1]], [[REG2]]
> +; CHECK-NEXT: cmp [[REG3]], #0
> ; CHECK-NEXT: csel x0, xzr, x3, ne
> ; CHECK-NEXT: ret
> %c0 = icmp slt i64 %v1, 0
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160606/97080fa5/attachment-0001.html>
More information about the llvm-commits
mailing list