[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