[llvm] r334553 - [DAGCombiner] Recognize more patterns for ABS
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 12 14:51:49 PDT 2018
Author: kparzysz
Date: Tue Jun 12 14:51:49 2018
New Revision: 334553
URL: http://llvm.org/viewvc/llvm-project?rev=334553&view=rev
Log:
[DAGCombiner] Recognize more patterns for ABS
Differential Revision: https://reviews.llvm.org/D47831
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td
llvm/trunk/test/CodeGen/Hexagon/abs.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=334553&r1=334552&r2=334553&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Jun 12 14:51:49 2018
@@ -2555,6 +2555,20 @@ SDValue DAGCombiner::visitSUB(SDNode *N)
if (N1.isUndef())
return N1;
+ // fold Y = sra (X, size(X)-1); sub (xor (X, Y), Y) -> (abs X)
+ if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
+ if (N0.getOpcode() == ISD::XOR && N1.getOpcode() == ISD::SRA) {
+ SDValue X0 = N0.getOperand(0), X1 = N0.getOperand(1);
+ SDValue S0 = N1.getOperand(0);
+ if ((X0 == S0 && X1 == N1) || (X0 == N1 && X1 == S0)) {
+ unsigned OpSizeInBits = VT.getScalarSizeInBits();
+ if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1)))
+ if (C->getAPIntValue() == (OpSizeInBits - 1))
+ return DAG.getNode(ISD::ABS, SDLoc(N), VT, S0);
+ }
+ }
+ }
+
// If the relocation model supports it, consider symbol offsets.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0))
if (!LegalOperations && TLI.isOffsetFoldingLegal(GA)) {
@@ -5660,13 +5674,19 @@ SDValue DAGCombiner::visitXOR(SDNode *N)
}
// fold Y = sra (X, size(X)-1); xor (add (X, Y), Y) -> (abs X)
- unsigned OpSizeInBits = VT.getScalarSizeInBits();
- if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 &&
- N1.getOpcode() == ISD::SRA && N1.getOperand(0) == N0.getOperand(0) &&
- TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
- if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1)))
- if (C->getAPIntValue() == (OpSizeInBits - 1))
- return DAG.getNode(ISD::ABS, SDLoc(N), VT, N0.getOperand(0));
+ if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
+ SDValue A = N0.getOpcode() == ISD::ADD ? N0 : N1;
+ SDValue S = N0.getOpcode() == ISD::SRA ? N0 : N1;
+ if (A.getOpcode() == ISD::ADD && S.getOpcode() == ISD::SRA) {
+ SDValue A0 = A.getOperand(0), A1 = A.getOperand(1);
+ SDValue S0 = S.getOperand(0);
+ if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0)) {
+ unsigned OpSizeInBits = VT.getScalarSizeInBits();
+ if (ConstantSDNode *C = isConstOrConstSplat(S.getOperand(1)))
+ if (C->getAPIntValue() == (OpSizeInBits - 1))
+ return DAG.getNode(ISD::ABS, SDLoc(N), VT, S0);
+ }
+ }
}
// fold (xor x, x) -> 0
Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=334553&r1=334552&r2=334553&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Tue Jun 12 14:51:49 2018
@@ -5392,23 +5392,19 @@ defm VABDLs : N3VLIntExt_QHS<0,1,0b011
defm VABDLu : N3VLIntExt_QHS<1,1,0b0111,0, IIC_VSUBi4Q,
"vabdl", "u", int_arm_neon_vabdu, zext, 1>;
+def : Pat<(v8i16 (abs (sub (zext (v8i8 DPR:$opA)), (zext (v8i8 DPR:$opB))))),
+ (VABDLuv8i16 DPR:$opA, DPR:$opB)>;
+def : Pat<(v4i32 (abs (sub (zext (v4i16 DPR:$opA)), (zext (v4i16 DPR:$opB))))),
+ (VABDLuv4i32 DPR:$opA, DPR:$opB)>;
+
+// ISD::ABS is not legal for v2i64, so VABDL needs to be matched from the
+// shift/xor pattern for ABS.
+
def abd_shr :
PatFrag<(ops node:$in1, node:$in2, node:$shift),
(NEONvshrs (sub (zext node:$in1),
(zext node:$in2)), (i32 $shift))>;
-def : Pat<(xor (v4i32 (bitconvert (v8i16 (abd_shr (v8i8 DPR:$opA), (v8i8 DPR:$opB), 15)))),
- (v4i32 (bitconvert (v8i16 (add (sub (zext (v8i8 DPR:$opA)),
- (zext (v8i8 DPR:$opB))),
- (v8i16 (abd_shr (v8i8 DPR:$opA), (v8i8 DPR:$opB), 15))))))),
- (VABDLuv8i16 DPR:$opA, DPR:$opB)>;
-
-def : Pat<(xor (v4i32 (abd_shr (v4i16 DPR:$opA), (v4i16 DPR:$opB), 31)),
- (v4i32 (add (sub (zext (v4i16 DPR:$opA)),
- (zext (v4i16 DPR:$opB))),
- (abd_shr (v4i16 DPR:$opA), (v4i16 DPR:$opB), 31)))),
- (VABDLuv4i32 DPR:$opA, DPR:$opB)>;
-
def : Pat<(xor (v4i32 (bitconvert (v2i64 (abd_shr (v2i32 DPR:$opA), (v2i32 DPR:$opB), 63)))),
(v4i32 (bitconvert (v2i64 (add (sub (zext (v2i32 DPR:$opA)),
(zext (v2i32 DPR:$opB))),
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=334553&r1=334552&r2=334553&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Tue Jun 12 14:51:49 2018
@@ -1327,6 +1327,9 @@ HexagonTargetLowering::HexagonTargetLowe
setMinimumJumpTableEntries(std::numeric_limits<int>::max());
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
+ setOperationAction(ISD::ABS, MVT::i32, Legal);
+ setOperationAction(ISD::ABS, MVT::i64, Legal);
+
// Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit,
// but they only operate on i64.
for (MVT VT : MVT::integer_valuetypes()) {
Modified: llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td?rev=334553&r1=334552&r2=334553&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td Tue Jun 12 14:51:49 2018
@@ -1194,22 +1194,6 @@ let Predicates = [HasV5T] in {
(i32 (LoReg $Rs)))>;
}
-let AddedComplexity = 50 in
-multiclass Abs_pat<InstHexagon MI, PatFrag RsPred, int Sh> {
- // Let y = x >> 31 (for 32-bit), i.e. the sign bit repeated.
- // abs(x) = (x + y) ^ y
- def: Pat<(xor (add (sra RsPred:$Rs, (i32 Sh)), RsPred:$Rs),
- (sra RsPred:$Rs, (i32 Sh))),
- (MI RsPred:$Rs)>;
- // abs(x) = (x ^ y) - y
- def: Pat<(sub (xor RsPred:$Rs, (sra RsPred:$Rs, (i32 Sh))),
- (sra RsPred:$Rs, (i32 Sh))),
- (MI RsPred:$Rs)>;
-}
-
-defm: Abs_pat<A2_abs, I32, 31>;
-defm: Abs_pat<A2_absp, I64, 63>;
-
def: Pat<(add I32:$Rs, anyimm:$s16), (A2_addi I32:$Rs, imm:$s16)>;
def: Pat<(or I32:$Rs, anyimm:$s10), (A2_orir I32:$Rs, imm:$s10)>;
def: Pat<(and I32:$Rs, anyimm:$s10), (A2_andir I32:$Rs, imm:$s10)>;
Modified: llvm/trunk/test/CodeGen/Hexagon/abs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/abs.ll?rev=334553&r1=334552&r2=334553&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/abs.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/abs.ll Tue Jun 12 14:51:49 2018
@@ -54,4 +54,30 @@ define i64 @f5(i64 %a0) #0 {
ret i64 %v2
}
-attributes #0 = { nounwind readnone "target-cpu"="hexagonv60" }
+; CHECK-LABEL: f6:
+; CHECK: r[[R60:[0-9]+]] = abs(r0)
+; CHECK: r[[R61:[0-9]+]] = asr(r0,#31)
+; CHECK: r0 = addasl(r[[R61]],r[[R60]],#1)
+define i32 @f6(i32 %a0) #0 {
+ %v0 = ashr i32 %a0, 31
+ %v1 = add i32 %a0, %v0
+ %v2 = xor i32 %v0, %v1
+ %v3 = mul i32 %v2, 2
+ %v4 = add i32 %v0, %v3
+ ret i32 %v4
+}
+
+; CHECK-LABEL: f7:
+; CHECK: r[[R70:[0-9]+]] = abs(r0)
+; CHECK: r[[R71:[0-9]+]] = asr(r0,#31)
+; CHECK: r0 = addasl(r[[R71]],r[[R70]],#1)
+define i32 @f7(i32 %a0) #0 {
+ %v0 = ashr i32 %a0, 31
+ %v1 = add i32 %v0, %a0
+ %v2 = xor i32 %v0, %v1
+ %v3 = shl i32 %v2, 1
+ %v4 = add i32 %v0, %v3
+ ret i32 %v4
+}
+
+attributes #0 = { nounwind readnone "target-cpu"="hexagonv60" "target-features"="-packets" }
More information about the llvm-commits
mailing list