[llvm] a0c3c60 - [InstCombine] fold shift-right-by-constant with shift-right-of-constant operand
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon May 30 12:34:15 PDT 2022
Author: Sanjay Patel
Date: 2022-05-30T15:30:01-04:00
New Revision: a0c3c60728ee5bc7d6ca40a5b6e446cde72c6700
URL: https://github.com/llvm/llvm-project/commit/a0c3c60728ee5bc7d6ca40a5b6e446cde72c6700
DIFF: https://github.com/llvm/llvm-project/commit/a0c3c60728ee5bc7d6ca40a5b6e446cde72c6700.diff
LOG: [InstCombine] fold shift-right-by-constant with shift-right-of-constant operand
(C2 >> X) >> C1 --> (C2 >> C1) >> X
The shift-left form of this transform has existed since:
16f18ed7b555bce5163
...but it applies to matching shift right opcodes too:
https://alive2.llvm.org/ce/z/c5eQms
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/test/Transforms/InstCombine/and.ll
llvm/test/Transforms/InstCombine/icmp-and-shift.ll
llvm/test/Transforms/InstCombine/shift-shift.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 8d5dbf83b7ea..b25c83a2a962 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -702,10 +702,18 @@ static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift,
}
}
-Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
+Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *C1,
BinaryOperator &I) {
+ // (C2 << X) << C1 --> (C2 << C1) << X
+ // (C2 >> X) >> C1 --> (C2 >> C1) >> X
+ Constant *C2;
+ Value *X;
+ if (match(Op0, m_BinOp(I.getOpcode(), m_Constant(C2), m_Value(X))))
+ return BinaryOperator::Create(I.getOpcode(),
+ ConstantExpr::get(I.getOpcode(), C2, C1), X);
+
const APInt *Op1C;
- if (!match(Op1, m_APInt(Op1C)))
+ if (!match(C1, m_APInt(Op1C)))
return nullptr;
// See if we can propagate this shift into the input, this covers the trivial
@@ -743,10 +751,10 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
if (match(Op0BO->getOperand(1), m_APInt(Op0C))) {
if (canShiftBinOpWithConstantRHS(I, Op0BO)) {
Constant *NewRHS = ConstantExpr::get(
- I.getOpcode(), cast<Constant>(Op0BO->getOperand(1)), Op1);
+ I.getOpcode(), cast<Constant>(Op0BO->getOperand(1)), C1);
Value *NewShift =
- Builder.CreateBinOp(I.getOpcode(), Op0BO->getOperand(0), Op1);
+ Builder.CreateBinOp(I.getOpcode(), Op0BO->getOperand(0), C1);
NewShift->takeName(Op0BO);
return BinaryOperator::Create(Op0BO->getOpcode(), NewShift, NewRHS);
@@ -772,9 +780,9 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
match(TBO->getOperand(1), m_APInt(C)) &&
canShiftBinOpWithConstantRHS(I, TBO)) {
Constant *NewRHS = ConstantExpr::get(
- I.getOpcode(), cast<Constant>(TBO->getOperand(1)), Op1);
+ I.getOpcode(), cast<Constant>(TBO->getOperand(1)), C1);
- Value *NewShift = Builder.CreateBinOp(I.getOpcode(), FalseVal, Op1);
+ Value *NewShift = Builder.CreateBinOp(I.getOpcode(), FalseVal, C1);
Value *NewOp = Builder.CreateBinOp(TBO->getOpcode(), NewShift, NewRHS);
return SelectInst::Create(Cond, NewOp, NewShift);
}
@@ -789,9 +797,9 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
match(FBO->getOperand(1), m_APInt(C)) &&
canShiftBinOpWithConstantRHS(I, FBO)) {
Constant *NewRHS = ConstantExpr::get(
- I.getOpcode(), cast<Constant>(FBO->getOperand(1)), Op1);
+ I.getOpcode(), cast<Constant>(FBO->getOperand(1)), C1);
- Value *NewShift = Builder.CreateBinOp(I.getOpcode(), TrueVal, Op1);
+ Value *NewShift = Builder.CreateBinOp(I.getOpcode(), TrueVal, C1);
Value *NewOp = Builder.CreateBinOp(FBO->getOpcode(), NewShift, NewRHS);
return SelectInst::Create(Cond, NewShift, NewOp);
}
@@ -1009,10 +1017,6 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
if (match(Op1, m_Constant(C1))) {
Constant *C2;
Value *X;
- // (C2 << X) << C1 --> (C2 << C1) << X
- if (match(Op0, m_Shl(m_Constant(C2), m_Value(X))))
- return BinaryOperator::CreateShl(ConstantExpr::getShl(C2, C1), X);
-
// (X * C2) << C1 --> X * (C2 << C1)
if (match(Op0, m_Mul(m_Value(X), m_Constant(C2))))
return BinaryOperator::CreateMul(X, ConstantExpr::getShl(C2, C1));
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index c7a63d7fc528..2617ac1eb6de 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -1699,8 +1699,7 @@ define i16 @shl_lshr_pow2_const_negative_overflow2(i16 %x) {
define i16 @lshr_lshr_pow2_const(i16 %x) {
; CHECK-LABEL: @lshr_lshr_pow2_const(
-; CHECK-NEXT: [[LSHR1:%.*]] = lshr i16 2048, [[X:%.*]]
-; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 [[LSHR1]], 6
+; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 32, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = and i16 [[LSHR2]], 4
; CHECK-NEXT: ret i16 [[R]]
;
@@ -1712,8 +1711,7 @@ define i16 @lshr_lshr_pow2_const(i16 %x) {
define i16 @lshr_lshr_pow2_const_negative_oneuse(i16 %x) {
; CHECK-LABEL: @lshr_lshr_pow2_const_negative_oneuse(
-; CHECK-NEXT: [[LSHR1:%.*]] = lshr i16 2048, [[X:%.*]]
-; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 [[LSHR1]], 6
+; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 32, [[X:%.*]]
; CHECK-NEXT: call void @use16(i16 [[LSHR2]])
; CHECK-NEXT: [[R:%.*]] = and i16 [[LSHR2]], 4
; CHECK-NEXT: ret i16 [[R]]
@@ -1727,8 +1725,7 @@ define i16 @lshr_lshr_pow2_const_negative_oneuse(i16 %x) {
define i16 @lshr_lshr_pow2_const_negative_nopow2_1(i16 %x) {
; CHECK-LABEL: @lshr_lshr_pow2_const_negative_nopow2_1(
-; CHECK-NEXT: [[LSHR1:%.*]] = lshr i16 2047, [[X:%.*]]
-; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 [[LSHR1]], 6
+; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 31, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = and i16 [[LSHR2]], 4
; CHECK-NEXT: ret i16 [[R]]
;
@@ -1740,8 +1737,7 @@ define i16 @lshr_lshr_pow2_const_negative_nopow2_1(i16 %x) {
define i16 @lshr_lshr_pow2_const_negative_nopow2_2(i16 %x) {
; CHECK-LABEL: @lshr_lshr_pow2_const_negative_nopow2_2(
-; CHECK-NEXT: [[LSHR1:%.*]] = lshr i16 8192, [[X:%.*]]
-; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 [[LSHR1]], 6
+; CHECK-NEXT: [[LSHR2:%.*]] = lshr i16 128, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = and i16 [[LSHR2]], 3
; CHECK-NEXT: ret i16 [[R]]
;
diff --git a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
index 6193692976a1..9c9f1a99e82d 100644
--- a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
@@ -335,8 +335,7 @@ define i32 @icmp_ne_and1_lshr_pow2(i32 %0) {
define <2 x i32> @icmp_ne_and1_lshr_pow2_vec(<2 x i32> %0) {
; CHECK-LABEL: @icmp_ne_and1_lshr_pow2_vec(
-; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> <i32 8, i32 8>, [[TMP0:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = lshr <2 x i32> [[LSHR]], <i32 2, i32 2>
+; CHECK-NEXT: [[AND:%.*]] = lshr <2 x i32> <i32 2, i32 2>, [[TMP0:%.*]]
; CHECK-NEXT: [[AND_LOBIT:%.*]] = and <2 x i32> [[AND]], <i32 1, i32 1>
; CHECK-NEXT: ret <2 x i32> [[AND_LOBIT]]
;
@@ -349,8 +348,7 @@ define <2 x i32> @icmp_ne_and1_lshr_pow2_vec(<2 x i32> %0) {
define i32 @icmp_eq_and_pow2_lshr_pow2(i32 %0) {
; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2(
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 8, [[TMP0:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[LSHR]], 2
+; CHECK-NEXT: [[AND:%.*]] = lshr i32 2, [[TMP0:%.*]]
; CHECK-NEXT: [[AND_LOBIT:%.*]] = and i32 [[AND]], 1
; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[AND_LOBIT]], 1
; CHECK-NEXT: ret i32 [[TMP2]]
@@ -375,8 +373,7 @@ define i32 @icmp_eq_and_pow2_lshr_pow2_case2(i32 %0) {
define <2 x i32> @icmp_eq_and_pow2_lshr_pow2_vec(<2 x i32> %0) {
; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2_vec(
-; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> <i32 8, i32 8>, [[TMP0:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = lshr <2 x i32> [[LSHR]], <i32 2, i32 2>
+; CHECK-NEXT: [[AND:%.*]] = lshr <2 x i32> <i32 2, i32 2>, [[TMP0:%.*]]
; CHECK-NEXT: [[AND_LOBIT:%.*]] = and <2 x i32> [[AND]], <i32 1, i32 1>
; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[AND_LOBIT]], <i32 1, i32 1>
; CHECK-NEXT: ret <2 x i32> [[TMP2]]
@@ -390,8 +387,7 @@ define <2 x i32> @icmp_eq_and_pow2_lshr_pow2_vec(<2 x i32> %0) {
define i32 @icmp_ne_and_pow2_lshr_pow2(i32 %0) {
; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2(
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 8, [[TMP0:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[LSHR]], 2
+; CHECK-NEXT: [[AND:%.*]] = lshr i32 2, [[TMP0:%.*]]
; CHECK-NEXT: [[AND_LOBIT:%.*]] = and i32 [[AND]], 1
; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[AND_LOBIT]], 1
; CHECK-NEXT: ret i32 [[TMP2]]
@@ -416,8 +412,7 @@ define i32 @icmp_ne_and_pow2_lshr_pow2_case2(i32 %0) {
define <2 x i32> @icmp_ne_and_pow2_lshr_pow2_vec(<2 x i32> %0) {
; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2_vec(
-; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> <i32 8, i32 8>, [[TMP0:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = lshr <2 x i32> [[LSHR]], <i32 2, i32 2>
+; CHECK-NEXT: [[AND:%.*]] = lshr <2 x i32> <i32 2, i32 2>, [[TMP0:%.*]]
; CHECK-NEXT: [[AND_LOBIT:%.*]] = and <2 x i32> [[AND]], <i32 1, i32 1>
; CHECK-NEXT: ret <2 x i32> [[AND_LOBIT]]
;
diff --git a/llvm/test/Transforms/InstCombine/shift-shift.ll b/llvm/test/Transforms/InstCombine/shift-shift.ll
index d76f3c00261a..aaf10f28b423 100644
--- a/llvm/test/Transforms/InstCombine/shift-shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift-shift.ll
@@ -277,7 +277,7 @@ define i32 @ashr_ashr_constants_use(i32 %x) {
; CHECK-LABEL: @ashr_ashr_constants_use(
; CHECK-NEXT: [[S:%.*]] = ashr i32 -33, [[X:%.*]]
; CHECK-NEXT: call void @use32(i32 [[S]])
-; CHECK-NEXT: [[R:%.*]] = ashr i32 [[S]], 3
+; CHECK-NEXT: [[R:%.*]] = ashr i32 -5, [[X]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = ashr i32 -33, %x
@@ -288,8 +288,7 @@ define i32 @ashr_ashr_constants_use(i32 %x) {
define <3 x i8> @ashr_ashr_constants_vec(<3 x i8> %x) {
; CHECK-LABEL: @ashr_ashr_constants_vec(
-; CHECK-NEXT: [[S:%.*]] = ashr <3 x i8> <i8 33, i8 -2, i8 -128>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = ashr <3 x i8> [[S]], <i8 3, i8 -1, i8 7>
+; CHECK-NEXT: [[R:%.*]] = ashr <3 x i8> <i8 4, i8 poison, i8 -1>, [[X:%.*]]
; CHECK-NEXT: ret <3 x i8> [[R]]
;
%s = ashr <3 x i8> <i8 33, i8 -2, i8 -128>, %x
@@ -301,7 +300,7 @@ define i32 @lshr_lshr_constants_use(i32 %x) {
; CHECK-LABEL: @lshr_lshr_constants_use(
; CHECK-NEXT: [[S:%.*]] = lshr i32 -33, [[X:%.*]]
; CHECK-NEXT: call void @use32(i32 [[S]])
-; CHECK-NEXT: [[R:%.*]] = lshr i32 [[S]], 3
+; CHECK-NEXT: [[R:%.*]] = lshr i32 536870907, [[X]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = lshr i32 -33, %x
@@ -312,8 +311,7 @@ define i32 @lshr_lshr_constants_use(i32 %x) {
define <3 x i8> @lshr_lshr_constants_vec(<3 x i8> %x) {
; CHECK-LABEL: @lshr_lshr_constants_vec(
-; CHECK-NEXT: [[S:%.*]] = lshr <3 x i8> <i8 33, i8 -2, i8 1>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = lshr <3 x i8> [[S]], <i8 3, i8 -1, i8 7>
+; CHECK-NEXT: [[R:%.*]] = lshr <3 x i8> <i8 4, i8 poison, i8 0>, [[X:%.*]]
; CHECK-NEXT: ret <3 x i8> [[R]]
;
%s = lshr <3 x i8> <i8 33, i8 -2, i8 1>, %x
More information about the llvm-commits
mailing list