diff options
| author | Chad Rosier <mcrosier@codeaurora.org> | 2016-10-26 18:15:32 +0000 |
|---|---|---|
| committer | Chad Rosier <mcrosier@codeaurora.org> | 2016-10-26 18:15:32 +0000 |
| commit | 0c621fda0d97b09fcc7699fdb3ce5350682ec3d4 (patch) | |
| tree | a0a92f1e3c153ff009213ca234e69a6b50cc306d /llvm/lib | |
| parent | 0cd95447db38eb6f246f644d566e6eb06276ca1d (diff) | |
| download | bcm5719-llvm-0c621fda0d97b09fcc7699fdb3ce5350682ec3d4.tar.gz bcm5719-llvm-0c621fda0d97b09fcc7699fdb3ce5350682ec3d4.zip | |
[AArch64] Avoid materializing constant 1 when generating cneg instructions.
Instead of
cmp w0, #1
orr w8, wzr, #0x1
cneg w0, w8, ne
we now generate
cmp w0, #1
csinv w0, w0, wzr, eq
PR28965
llvm-svn: 285217
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index d9e61aa936b..076145c36b2 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -4054,8 +4054,9 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS, // Avoid materializing a constant when possible by reusing a known value in // a register. However, don't perform this optimization if the known value - // is one, zero or negative one. We can always materialize these values - // using CSINC, CSEL and CSINV with wzr/xzr as the FVal, respectively. + // is one, zero or negative one in the case of a CSEL. We can always + // materialize these values using CSINC, CSEL and CSINV with wzr/xzr as the + // FVal, respectively. ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS); if (Opcode == AArch64ISD::CSEL && RHSVal && !RHSVal->isOne() && !RHSVal->isNullValue() && !RHSVal->isAllOnesValue()) { @@ -4066,6 +4067,16 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS, TVal = LHS; else if (CFVal && CFVal == RHSVal && AArch64CC == AArch64CC::NE) FVal = LHS; + } else if (Opcode == AArch64ISD::CSNEG && RHSVal && RHSVal->isOne()) { + assert (CTVal && CFVal && "Expected constant operands for CSNEG."); + // Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to + // avoid materializing C. + AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC); + if (CTVal == RHSVal && AArch64CC == AArch64CC::EQ) { + Opcode = AArch64ISD::CSINV; + TVal = LHS; + FVal = DAG.getConstant(0, dl, FVal.getValueType()); + } } SDValue CCVal; |

