[llvm] 8299c76 - [InstSimplify] Simplify icmp between Shl instructions of the same value

Matt Devereau via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 20 01:35:38 PST 2023


Author: Matt Devereau
Date: 2023-02-20T09:25:34Z
New Revision: 8299c764bd2d313334dcbabf9dd0a1f872a78612

URL: https://github.com/llvm/llvm-project/commit/8299c764bd2d313334dcbabf9dd0a1f872a78612
DIFF: https://github.com/llvm/llvm-project/commit/8299c764bd2d313334dcbabf9dd0a1f872a78612.diff

LOG: [InstSimplify] Simplify icmp between Shl instructions of the same value

define i1 @compare_vscales() {
  %vscale = call i64 @llvm.vscale.i64()
  %vscalex2 = shl nuw nsw i64 %vscale, 1
  %vscalex4 = shl nuw nsw i64 %vscale, 2
  %cmp = icmp ult i64 %vscalex2, %vscalex4
  ret i1 %cmp
}

This IR is currently emitted by LLVM. This icmp is redundant as this snippet
can be simplified to true or false as both operands originate from the same
@llvm.vscale.i64() call.

Differential Revision: https://reviews.llvm.org/D142542

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/compare.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 9f294dfb4f20..a20aeaa203f3 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3394,8 +3394,26 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
       return ConstantInt::getTrue(getCompareTy(RHS));
   }
 
-  if (MaxRecurse && LBO && RBO && LBO->getOpcode() == RBO->getOpcode() &&
-      LBO->getOperand(1) == RBO->getOperand(1)) {
+  if (!MaxRecurse || !LBO || !RBO || LBO->getOpcode() != RBO->getOpcode())
+    return nullptr;
+
+  if (LBO->getOperand(0) == RBO->getOperand(0)) {
+    switch (LBO->getOpcode()) {
+    default:
+      break;
+    case Instruction::Shl:
+      bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO);
+      bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO);
+      if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) ||
+          !isKnownNonZero(LBO->getOperand(0), Q.DL))
+        break;
+      if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(1),
+                                      RBO->getOperand(1), Q, MaxRecurse - 1))
+        return V;
+    }
+  }
+
+  if (LBO->getOperand(1) == RBO->getOperand(1)) {
     switch (LBO->getOpcode()) {
     default:
       break;

diff  --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll
index c0e51f15d18e..844b732f54ad 100644
--- a/llvm/test/Transforms/InstSimplify/compare.ll
+++ b/llvm/test/Transforms/InstSimplify/compare.ll
@@ -2815,11 +2815,7 @@ define i1 @neg_global_alias() {
 
 define i1 @icmp_lshr_known_non_zero_ult_true(i8 %x) {
 ; CHECK-LABEL: @icmp_lshr_known_non_zero_ult_true(
-; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[X1:%.*]] = shl nuw i8 [[OR]], 1
-; CHECK-NEXT:    [[X2:%.*]] = shl nuw i8 [[OR]], 2
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X1]], [[X2]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %or = or i8 %x, 1
   %x1 = shl nuw i8 %or, 1
@@ -2830,11 +2826,7 @@ define i1 @icmp_lshr_known_non_zero_ult_true(i8 %x) {
 
 define i1 @icmp_lshr_known_non_zero_ult_false(i8 %x) {
 ; CHECK-LABEL: @icmp_lshr_known_non_zero_ult_false(
-; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[X1:%.*]] = shl nuw i8 [[OR]], 1
-; CHECK-NEXT:    [[X2:%.*]] = shl nuw i8 [[OR]], 2
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X1]], [[X2]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
   %or = or i8 %x, 1
   %x1 = shl nuw i8 %or, 1
@@ -2845,11 +2837,7 @@ define i1 @icmp_lshr_known_non_zero_ult_false(i8 %x) {
 
 define i1 @icmp_lshr_known_non_zero_slt_true(i8 %x) {
 ; CHECK-LABEL: @icmp_lshr_known_non_zero_slt_true(
-; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[X1:%.*]] = shl nuw nsw i8 [[OR]], 1
-; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw i8 [[OR]], 2
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X1]], [[X2]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %or = or i8 %x, 1
   %x1 = shl nuw nsw i8 %or, 1
@@ -2860,11 +2848,7 @@ define i1 @icmp_lshr_known_non_zero_slt_true(i8 %x) {
 
 define i1 @icmp_lshr_known_non_zero_slt_false(i8 %x) {
 ; CHECK-LABEL: @icmp_lshr_known_non_zero_slt_false(
-; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[X1:%.*]] = shl nuw nsw i8 [[OR]], 2
-; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw i8 [[OR]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X1]], [[X2]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
   %or = or i8 %x, 1
   %x1 = shl nuw nsw i8 %or, 2
@@ -2888,6 +2872,21 @@ define i1 @neg_icmp_lshr_known_non_zero_slt_no_nsw(i8 %x) {
   ret i1 %cmp
 }
 
+define i1 @neg_icmp_lshr_known_non_zero_ult_no_nuw(i8 %x) {
+; CHECK-LABEL: @neg_icmp_lshr_known_non_zero_ult_no_nuw(
+; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 1
+; CHECK-NEXT:    [[X1:%.*]] = shl i8 [[OR]], 1
+; CHECK-NEXT:    [[X2:%.*]] = shl i8 [[OR]], 2
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X1]], [[X2]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %or = or i8 %x, 1
+  %x1 = shl i8 %or, 1
+  %x2 = shl i8 %or, 2
+  %cmp = icmp slt i8 %x1, %x2
+  ret i1 %cmp
+}
+
 define i1 @neg_icmp_lshr_known_non_zero_slt_no_nuw(i8 %x) {
 ; CHECK-LABEL: @neg_icmp_lshr_known_non_zero_slt_no_nuw(
 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 1
@@ -2946,11 +2945,7 @@ define i1 @neg_icmp_lshr_
diff erent_shift_values(i8 %x, i8 %y) {
 
 define i1 @icmp_ult_vscale_true(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_ult_vscale_true(
-; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
-; CHECK-NEXT:    [[X1:%.*]] = shl nuw nsw i64 [[VSCALE]], 1
-; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw i64 [[VSCALE]], 2
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X1]], [[X2]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %vscale = call i64 @llvm.vscale.i64()
   %x1 = shl nuw nsw i64 %vscale, 1
@@ -2961,11 +2956,7 @@ define i1 @icmp_ult_vscale_true(i8 %x, i8 %y) {
 
 define i1 @icmp_ult_vscale_false(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_ult_vscale_false(
-; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
-; CHECK-NEXT:    [[X1:%.*]] = shl nuw nsw i64 [[VSCALE]], 1
-; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw i64 [[VSCALE]], 2
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[X1]], [[X2]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
   %vscale = call i64 @llvm.vscale.i64()
   %x1 = shl nuw nsw i64 %vscale, 1


        


More information about the llvm-commits mailing list