[llvm] 3885879 - [DAGCombine] Add simple folds for SSHLSAT/USHLSAT
Bjorn Pettersson via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 1 01:52:11 PST 2022
Author: Bjorn Pettersson
Date: 2022-02-01T10:51:35+01:00
New Revision: 38858790467e5e8d9e7894b26c0d05ec4516c4cb
URL: https://github.com/llvm/llvm-project/commit/38858790467e5e8d9e7894b26c0d05ec4516c4cb
DIFF: https://github.com/llvm/llvm-project/commit/38858790467e5e8d9e7894b26c0d05ec4516c4cb.diff
LOG: [DAGCombine] Add simple folds for SSHLSAT/USHLSAT
Do "simplifyShift" and "FoldConstantArithmetic" folds for the SSHLSAT
and USHLSAT DAG nodes.
This includes folds such as:
(shlsat undef/poison, x) -> 0
(shlsat x, undef/poison) -> undef
(shlsat x, too_large_shamt) -> undef
(shlsat 0, x) -> 0
(shlsat x, 0) -> x
(shlsat c1, c2) -> c3
Differential Revision: https://reviews.llvm.org/D118603
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/test/CodeGen/AArch64/sshl_sat.ll
llvm/test/CodeGen/AArch64/ushl_sat.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 1957f5231bdf..0ed2bd9d6d62 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -440,6 +440,7 @@ namespace {
SDValue visitSRA(SDNode *N);
SDValue visitSRL(SDNode *N);
SDValue visitFunnelShift(SDNode *N);
+ SDValue visitSHLSAT(SDNode *N);
SDValue visitRotate(SDNode *N);
SDValue visitABS(SDNode *N);
SDValue visitBSWAP(SDNode *N);
@@ -1652,6 +1653,8 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::ROTL: return visitRotate(N);
case ISD::FSHL:
case ISD::FSHR: return visitFunnelShift(N);
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT: return visitSHLSAT(N);
case ISD::ABS: return visitABS(N);
case ISD::BSWAP: return visitBSWAP(N);
case ISD::BITREVERSE: return visitBITREVERSE(N);
@@ -9346,6 +9349,22 @@ SDValue DAGCombiner::visitFunnelShift(SDNode *N) {
return SDValue();
}
+SDValue DAGCombiner::visitSHLSAT(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ if (SDValue V = DAG.simplifyShift(N0, N1))
+ return V;
+
+ EVT VT = N0.getValueType();
+
+ // fold (*shlsat c1, c2) -> c1<<c2
+ if (SDValue C =
+ DAG.FoldConstantArithmetic(N->getOpcode(), SDLoc(N), VT, {N0, N1}))
+ return C;
+
+ return SDValue();
+}
+
// Given a ABS node, detect the following pattern:
// (ABS (SUB (EXTEND a), (EXTEND b))).
// Generates UABD/SABD instruction.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 240dcca654ae..cf42a2200564 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5242,6 +5242,8 @@ static llvm::Optional<APInt> FoldValue(unsigned Opcode, const APInt &C1,
case ISD::UADDSAT: return C1.uadd_sat(C2);
case ISD::SSUBSAT: return C1.ssub_sat(C2);
case ISD::USUBSAT: return C1.usub_sat(C2);
+ case ISD::SSHLSAT: return C1.sshl_sat(C2);
+ case ISD::USHLSAT: return C1.ushl_sat(C2);
case ISD::UDIV:
if (!C2.getBoolValue())
break;
diff --git a/llvm/test/CodeGen/AArch64/sshl_sat.ll b/llvm/test/CodeGen/AArch64/sshl_sat.ll
index 208c339dea0d..a63cd3241a0e 100644
--- a/llvm/test/CodeGen/AArch64/sshl_sat.ll
+++ b/llvm/test/CodeGen/AArch64/sshl_sat.ll
@@ -8,12 +8,7 @@ declare <4 x i16> @llvm.sshl.sat.v4i16(<4 x i16>, <4 x i16>)
define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_undef:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: mov w9, #-2147483648
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: cinv w9, w9, ge
-; CHECK-NEXT: csel w8, w9, w8, ne
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 undef, i16 %y)
ret i16 %tmp
@@ -23,13 +18,6 @@ define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_by_undef:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w9, w0, #16
-; CHECK-NEXT: mov w8, #-2147483648
-; CHECK-NEXT: cmp w9, #0
-; CHECK-NEXT: cinv w8, w8, ge
-; CHECK-NEXT: cmp w9, w9
-; CHECK-NEXT: csel w8, w8, w9, ne
-; CHECK-NEXT: asr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 undef)
ret i16 %tmp
@@ -39,12 +27,7 @@ define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_poison:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: mov w9, #-2147483648
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: cinv w9, w9, ge
-; CHECK-NEXT: csel w8, w9, w8, ne
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 poison, i16 %y)
ret i16 %tmp
@@ -54,13 +37,6 @@ define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_by_poison:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w9, w0, #16
-; CHECK-NEXT: mov w8, #-2147483648
-; CHECK-NEXT: cmp w9, #0
-; CHECK-NEXT: cinv w8, w8, ge
-; CHECK-NEXT: cmp w9, w9
-; CHECK-NEXT: csel w8, w8, w9, ne
-; CHECK-NEXT: asr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 poison)
ret i16 %tmp
@@ -70,12 +46,6 @@ define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_by_bitwidth:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w9, w0, #16
-; CHECK-NEXT: mov w8, #-2147483648
-; CHECK-NEXT: cmp w9, #0
-; CHECK-NEXT: cinv w8, w8, ge
-; CHECK-NEXT: csel w8, w8, wzr, ne
-; CHECK-NEXT: asr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 16)
ret i16 %tmp
@@ -85,12 +55,7 @@ define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_zero:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: mov w9, #-2147483648
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: cinv w9, w9, ge
-; CHECK-NEXT: csel w8, w9, w8, ne
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 0, i16 %y)
ret i16 %tmp
@@ -100,13 +65,6 @@ define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_by_zero:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w9, w0, #16
-; CHECK-NEXT: mov w8, #-2147483648
-; CHECK-NEXT: cmp w9, #0
-; CHECK-NEXT: cinv w8, w8, ge
-; CHECK-NEXT: cmp w9, w9
-; CHECK-NEXT: csel w8, w8, w9, ne
-; CHECK-NEXT: asr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 0)
ret i16 %tmp
@@ -116,14 +74,7 @@ define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_constfold:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #524288
-; CHECK-NEXT: mov w9, #-2147483648
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: cinv w9, w9, ge
-; CHECK-NEXT: cmp w8, #128, lsl #12 // =524288
-; CHECK-NEXT: mov w8, #2097152
-; CHECK-NEXT: csel w8, w9, w8, ne
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: mov w0, #32
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 8, i16 2)
ret i16 %tmp
@@ -133,12 +84,7 @@ define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_satmax(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_satmax:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #524288
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: mov w8, #-2147483648
-; CHECK-NEXT: cinv w8, w8, ge
-; CHECK-NEXT: csel w8, w8, wzr, ne
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: mov w0, #32767
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 8, i16 15)
ret i16 %tmp
@@ -148,12 +94,7 @@ define i16 @combine_shlsat_satmax(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_satmin(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_satmin:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #-524288
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: mov w8, #-2147483648
-; CHECK-NEXT: cinv w8, w8, ge
-; CHECK-NEXT: csel w8, w8, wzr, ne
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: mov w0, #32768
; CHECK-NEXT: ret
%tmp = call i16 @llvm.sshl.sat.i16(i16 -8, i16 15)
ret i16 %tmp
@@ -166,33 +107,10 @@ define void @combine_shlsat_vector() nounwind {
; CHECK-LABEL: combine_shlsat_vector:
; CHECK: // %bb.0:
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-NEXT: mov w8, #524288
-; CHECK-NEXT: mov w9, #-2147483648
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: cinv w10, w9, ge
-; CHECK-NEXT: csel w11, w10, wzr, ne
-; CHECK-NEXT: cmp w8, #128, lsl #12 // =524288
-; CHECK-NEXT: mov w8, #2097152
-; CHECK-NEXT: asr w11, w11, #16
-; CHECK-NEXT: csel w8, w10, w8, ne
-; CHECK-NEXT: mov w10, #-524288
-; CHECK-NEXT: asr w8, w8, #16
-; CHECK-NEXT: cmp w10, #0
-; CHECK-NEXT: cinv w9, w9, ge
-; CHECK-NEXT: fmov s0, w8
-; CHECK-NEXT: csel w8, w9, wzr, ne
-; CHECK-NEXT: cmn w10, #128, lsl #12 // =524288
-; CHECK-NEXT: mov w10, #-2097152
-; CHECK-NEXT: csel w9, w9, w10, ne
-; CHECK-NEXT: asr w8, w8, #16
-; CHECK-NEXT: mov v0.h[1], w11
-; CHECK-NEXT: asr w9, w9, #16
-; CHECK-NEXT: mov v0.h[2], w9
-; CHECK-NEXT: mov v0.h[3], w8
-; CHECK-NEXT: umov w0, v0.h[0]
-; CHECK-NEXT: umov w1, v0.h[1]
-; CHECK-NEXT: umov w2, v0.h[2]
-; CHECK-NEXT: umov w3, v0.h[3]
+; CHECK-NEXT: mov w0, #32
+; CHECK-NEXT: mov w1, #32767
+; CHECK-NEXT: mov w2, #65504
+; CHECK-NEXT: mov w3, #32768
; CHECK-NEXT: bl sink4xi16
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/ushl_sat.ll b/llvm/test/CodeGen/AArch64/ushl_sat.ll
index 0a1373bf487f..f6ccd09374ab 100644
--- a/llvm/test/CodeGen/AArch64/ushl_sat.ll
+++ b/llvm/test/CodeGen/AArch64/ushl_sat.ll
@@ -8,10 +8,7 @@ declare <2 x i16> @llvm.ushl.sat.v2i16(<2 x i16>, <2 x i16>)
define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_undef:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csetm w8, ne
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 undef, i16 %y)
ret i16 %tmp
@@ -21,10 +18,6 @@ define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_by_undef:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w8, w0, #16
-; CHECK-NEXT: cmp w8, w8
-; CHECK-NEXT: csinv w8, w8, wzr, eq
-; CHECK-NEXT: lsr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 undef)
ret i16 %tmp
@@ -34,10 +27,7 @@ define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_poison:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csetm w8, ne
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 poison, i16 %y)
ret i16 %tmp
@@ -47,10 +37,6 @@ define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_by_poison:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w8, w0, #16
-; CHECK-NEXT: cmp w8, w8
-; CHECK-NEXT: csinv w8, w8, wzr, eq
-; CHECK-NEXT: lsr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 poison)
ret i16 %tmp
@@ -60,10 +46,6 @@ define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_by_bitwidth:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w8, w0, #16
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csetm w8, ne
-; CHECK-NEXT: lsr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 16)
ret i16 %tmp
@@ -73,10 +55,7 @@ define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shl_zero:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csetm w8, ne
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 0, i16 %y)
ret i16 %tmp
@@ -86,10 +65,6 @@ define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_by_zero:
; CHECK: // %bb.0:
-; CHECK-NEXT: lsl w8, w0, #16
-; CHECK-NEXT: cmp w8, w8
-; CHECK-NEXT: csinv w8, w8, wzr, eq
-; CHECK-NEXT: lsr w0, w8, #16
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 0)
ret i16 %tmp
@@ -99,11 +74,7 @@ define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_constfold:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #524288
-; CHECK-NEXT: cmp w8, #128, lsl #12 // =524288
-; CHECK-NEXT: mov w8, #2097152
-; CHECK-NEXT: csinv w8, w8, wzr, eq
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: mov w0, #32
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 8, i16 2)
ret i16 %tmp
@@ -113,10 +84,7 @@ define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
define i16 @combine_shlsat_satmax(i16 %x, i16 %y) nounwind {
; CHECK-LABEL: combine_shlsat_satmax:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #524288
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csetm w8, ne
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: mov w0, #65535
; CHECK-NEXT: ret
%tmp = call i16 @llvm.ushl.sat.i16(i16 8, i16 15)
ret i16 %tmp
@@ -130,17 +98,8 @@ define void @combine_shlsat_vector() nounwind {
; CHECK-LABEL: combine_shlsat_vector:
; CHECK: // %bb.0:
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-NEXT: mov w8, #524288
-; CHECK-NEXT: mov w9, #2097152
-; CHECK-NEXT: cmp w8, #128, lsl #12 // =524288
-; CHECK-NEXT: csinv w9, w9, wzr, eq
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csetm w8, ne
-; CHECK-NEXT: fmov s0, w9
-; CHECK-NEXT: mov v0.s[1], w8
-; CHECK-NEXT: ushr v0.2s, v0.2s, #16
-; CHECK-NEXT: mov w1, v0.s[1]
-; CHECK-NEXT: fmov w0, s0
+; CHECK-NEXT: mov w0, #32
+; CHECK-NEXT: mov w1, #65535
; CHECK-NEXT: bl sink2xi16
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: ret
More information about the llvm-commits
mailing list