[PATCH] D131956: [JumpThreading] Process range comparisions with non-local cmp instructions

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 2 03:22:56 PDT 2022


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbe37caca0055: [JumpThreading] Process range comparisions with non-local cmp instructions (authored by kachkov98, committed by nikic).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131956/new/

https://reviews.llvm.org/D131956

Files:
  llvm/lib/Transforms/Scalar/JumpThreading.cpp
  llvm/test/Transforms/JumpThreading/range-compare.ll


Index: llvm/test/Transforms/JumpThreading/range-compare.ll
===================================================================
--- llvm/test/Transforms/JumpThreading/range-compare.ll
+++ llvm/test/Transforms/JumpThreading/range-compare.ll
@@ -123,3 +123,42 @@
   ret void
 }
 
+; Make sure we thread the false side of the first if to the end of the function
+; (case with non-local comparisions).
+define void @test4(i32 %x) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 9
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X]], -3
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[X_OFF]], 5
+; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_END:%.*]], label [[IF_END4:%.*]]
+; CHECK:       if.end:
+; CHECK-NEXT:    call void (...) @bar()
+; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4]]
+; CHECK:       if.then3:
+; CHECK-NEXT:    call void (...) @baz()
+; CHECK-NEXT:    br label [[IF_END4]]
+; CHECK:       if.end4:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %cmp1 = icmp slt i32 %x, 9
+  %x.off = add i32 %x, -3
+  %cmp2 = icmp ult i32 %x.off, 5
+  br i1 %cmp1, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void (...) @bar()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  br i1 %cmp2, label %if.then3, label %if.end4
+
+if.then3:                                         ; preds = %if.end
+  call void (...) @baz()
+  br label %if.end4
+
+if.end4:                                          ; preds = %if.then3, %if.end
+  ret void
+}
+
Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -654,22 +654,25 @@
   Instruction *I = dyn_cast<Instruction>(V);
   if (!I || I->getParent() != BB) {
 
-    // Okay, if this is a live-in value, see if it has a known value at the end
-    // of any of our predecessors.
-    //
-    // FIXME: This should be an edge property, not a block end property.
-    /// TODO: Per PR2563, we could infer value range information about a
-    /// predecessor based on its terminator.
-    //
-    // FIXME: change this to use the more-rich 'getPredicateOnEdge' method if
-    // "I" is a non-local compare-with-a-constant instruction.  This would be
-    // able to handle value inequalities better, for example if the compare is
-    // "X < 4" and "X < 3" is known true but "X < 4" itself is not available.
-    // Perhaps getConstantOnEdge should be smart enough to do this?
+    // Okay, if this is a live-in value, see if it has a known value at the any
+    // edge from our predecessors.
     for (BasicBlock *P : predecessors(BB)) {
+      using namespace PatternMatch;
       // If the value is known by LazyValueInfo to be a constant in a
       // predecessor, use that information to try to thread this block.
       Constant *PredCst = LVI->getConstantOnEdge(V, P, BB, CxtI);
+      // If I is a non-local compare-with-constant instruction, use more-rich
+      // 'getPredicateOnEdge' method. This would be able to handle value
+      // inequalities better, for example if the compare is "X < 4" and "X < 3"
+      // is known true but "X < 4" itself is not available.
+      CmpInst::Predicate Pred;
+      Value *Val;
+      Constant *Cst;
+      if (!PredCst && match(V, m_Cmp(Pred, m_Value(Val), m_Constant(Cst)))) {
+        auto Res = LVI->getPredicateOnEdge(Pred, Val, Cst, P, BB, CxtI);
+        if (Res != LazyValueInfo::Unknown)
+          PredCst = ConstantInt::getBool(V->getContext(), Res);
+      }
       if (Constant *KC = getKnownConstant(PredCst, Preference))
         Result.emplace_back(KC, P);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131956.457552.patch
Type: text/x-patch
Size: 3827 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220902/8fe439e2/attachment.bin>


More information about the llvm-commits mailing list