[llvm] 204038d - [InstSimplify] fold or+shifted -1 to -1
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 24 12:38:47 PDT 2021
Author: Sanjay Patel
Date: 2021-08-24T15:38:38-04:00
New Revision: 204038d52e03811cc39c18cc073c6020fbae4a4b
URL: https://github.com/llvm/llvm-project/commit/204038d52e03811cc39c18cc073c6020fbae4a4b
DIFF: https://github.com/llvm/llvm-project/commit/204038d52e03811cc39c18cc073c6020fbae4a4b.diff
LOG: [InstSimplify] fold or+shifted -1 to -1
These are similar to the rotate pattern added with:
dcf659e8219b
...but we don't have guard ops on the shift amount,
so we don't canonicalize to the intrinsic.
declare void @llvm.assume(i1)
define i32 @src(i32 %shamt, i32 %bitwidth) {
; subtract must be in range of bitwidth
%lt = icmp ule i32 %bitwidth, 32
call void @llvm.assume(i1 %lt)
%r = lshr i32 -1, %shamt
%s = sub i32 %bitwidth, %shamt
%l = shl i32 -1, %s
%o = or i32 %r, %l
ret i32 %o
}
define i32 @tgt(i32 %shamt, i32 %bitwidth) {
ret i32 -1
}
https://alive2.llvm.org/ce/z/aF7WHx
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/or.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 5536de590e1b4..331442cf2b495 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2276,6 +2276,23 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
match(Op0, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
return NotA;
+ // Rotated -1 is still -1:
+ // (-1 << X) | (-1 >> (C - X)) --> -1
+ // (-1 >> X) | (-1 << (C - X)) --> -1
+ // ...with C <= bitwidth (and commuted variants).
+ Value *X, *Y;
+ if ((match(Op0, m_Shl(m_AllOnes(), m_Value(X))) &&
+ match(Op1, m_LShr(m_AllOnes(), m_Value(Y)))) ||
+ (match(Op1, m_Shl(m_AllOnes(), m_Value(X))) &&
+ match(Op0, m_LShr(m_AllOnes(), m_Value(Y))))) {
+ const APInt *C;
+ if ((match(X, m_Sub(m_APInt(C), m_Specific(Y))) ||
+ match(Y, m_Sub(m_APInt(C), m_Specific(X)))) &&
+ C->ule(X->getType()->getScalarSizeInBits())) {
+ return ConstantInt::getAllOnesValue(X->getType());
+ }
+ }
+
if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
return V;
diff --git a/llvm/test/Transforms/InstSimplify/or.ll b/llvm/test/Transforms/InstSimplify/or.ll
index 45bfafe54ffa6..6938b66989c3d 100644
--- a/llvm/test/Transforms/InstSimplify/or.ll
+++ b/llvm/test/Transforms/InstSimplify/or.ll
@@ -448,11 +448,7 @@ define i32 @and_or_not_or8(i32 %A, i32 %B) {
define i32 @shifted_all_ones(i32 %shamt) {
; CHECK-LABEL: @shifted_all_ones(
-; CHECK-NEXT: [[R:%.*]] = lshr i32 -1, [[SHAMT:%.*]]
-; CHECK-NEXT: [[S:%.*]] = sub i32 32, [[SHAMT]]
-; CHECK-NEXT: [[L:%.*]] = shl i32 -1, [[S]]
-; CHECK-NEXT: [[O:%.*]] = or i32 [[R]], [[L]]
-; CHECK-NEXT: ret i32 [[O]]
+; CHECK-NEXT: ret i32 -1
;
%r = lshr i32 -1, %shamt
%s = sub i32 32, %shamt
@@ -461,13 +457,11 @@ define i32 @shifted_all_ones(i32 %shamt) {
ret i32 %o
}
+; Sub from less than bitwidth is ok (overlapping ones).
+
define i32 @shifted_all_ones_commute(i32 %shamt) {
; CHECK-LABEL: @shifted_all_ones_commute(
-; CHECK-NEXT: [[R:%.*]] = lshr i32 -1, [[SHAMT:%.*]]
-; CHECK-NEXT: [[S:%.*]] = sub i32 31, [[SHAMT]]
-; CHECK-NEXT: [[L:%.*]] = shl i32 -1, [[S]]
-; CHECK-NEXT: [[O:%.*]] = or i32 [[L]], [[R]]
-; CHECK-NEXT: ret i32 [[O]]
+; CHECK-NEXT: ret i32 -1
;
%r = lshr i32 -1, %shamt
%s = sub i32 31, %shamt
@@ -478,11 +472,7 @@ define i32 @shifted_all_ones_commute(i32 %shamt) {
define <2 x i9> @shifted_all_ones_sub_on_lshr(<2 x i9> %shamt) {
; CHECK-LABEL: @shifted_all_ones_sub_on_lshr(
-; CHECK-NEXT: [[L:%.*]] = shl <2 x i9> <i9 -1, i9 -1>, [[SHAMT:%.*]]
-; CHECK-NEXT: [[S:%.*]] = sub <2 x i9> <i9 5, i9 5>, [[SHAMT]]
-; CHECK-NEXT: [[R:%.*]] = lshr <2 x i9> <i9 -1, i9 -1>, [[S]]
-; CHECK-NEXT: [[O:%.*]] = or <2 x i9> [[L]], [[R]]
-; CHECK-NEXT: ret <2 x i9> [[O]]
+; CHECK-NEXT: ret <2 x i9> <i9 -1, i9 -1>
;
%l = shl <2 x i9> <i9 -1, i9 -1>, %shamt
%s = sub <2 x i9> <i9 5, i9 5>, %shamt
@@ -493,11 +483,7 @@ define <2 x i9> @shifted_all_ones_sub_on_lshr(<2 x i9> %shamt) {
define i8 @shifted_all_ones_sub_on_lshr_commute(i8 %shamt) {
; CHECK-LABEL: @shifted_all_ones_sub_on_lshr_commute(
-; CHECK-NEXT: [[L:%.*]] = shl i8 -1, [[SHAMT:%.*]]
-; CHECK-NEXT: [[S:%.*]] = sub i8 8, [[SHAMT]]
-; CHECK-NEXT: [[R:%.*]] = lshr i8 -1, [[S]]
-; CHECK-NEXT: [[O:%.*]] = or i8 [[R]], [[L]]
-; CHECK-NEXT: ret i8 [[O]]
+; CHECK-NEXT: ret i8 -1
;
%l = shl i8 -1, %shamt
%s = sub i8 8, %shamt
@@ -506,6 +492,8 @@ define i8 @shifted_all_ones_sub_on_lshr_commute(i8 %shamt) {
ret i8 %o
}
+; negative test - need -1 in general case
+
define i32 @shifted_not_all_ones(i32 %shamt) {
; CHECK-LABEL: @shifted_not_all_ones(
; CHECK-NEXT: [[R:%.*]] = lshr i32 -2, [[SHAMT:%.*]]
@@ -521,6 +509,8 @@ define i32 @shifted_not_all_ones(i32 %shamt) {
ret i32 %o
}
+; negative test - opposite shift amount may be too big
+
define i32 @shifted_all_ones_greater_than_bitwidth(i32 %shamt) {
; CHECK-LABEL: @shifted_all_ones_greater_than_bitwidth(
; CHECK-NEXT: [[R:%.*]] = lshr i32 -1, [[SHAMT:%.*]]
@@ -535,3 +525,20 @@ define i32 @shifted_all_ones_greater_than_bitwidth(i32 %shamt) {
%o = or i32 %r, %l
ret i32 %o
}
+
+; negative test - shift amount must be derived from same base
+
+define i32 @shifted_all_ones_not_same_amt(i32 %shamt, i32 %other) {
+; CHECK-LABEL: @shifted_all_ones_not_same_amt(
+; CHECK-NEXT: [[R:%.*]] = lshr i32 -1, [[SHAMT:%.*]]
+; CHECK-NEXT: [[S:%.*]] = sub i32 32, [[OTHER:%.*]]
+; CHECK-NEXT: [[L:%.*]] = shl i32 -1, [[S]]
+; CHECK-NEXT: [[O:%.*]] = or i32 [[R]], [[L]]
+; CHECK-NEXT: ret i32 [[O]]
+;
+ %r = lshr i32 -1, %shamt
+ %s = sub i32 32, %other
+ %l = shl i32 -1, %s
+ %o = or i32 %r, %l
+ ret i32 %o
+}
More information about the llvm-commits
mailing list