[llvm] GVN: generalize impliesEquivalence (NFC) (PR #111416)

via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 11:16:54 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Ramkumar Ramachandra (artagnon)

<details>
<summary>Changes</summary>

impliesEquivalenceIfTrue and impliesEquivalenceIfFalse can be extended to aggregates easily, although as the added tests show, the codepath cannot be exercised: GVN does not propogate values through a vector-select. Generalize the code anyway, as it opens up opportunities for optimizing GVN. While at it, note that the optimization is invalid for the no-signed-zeros case, and strip the bad FIXME.

 Alive2 proof: https://alive2.llvm.org/ce/z/vEaK8M

-- 8< --
Based on #<!-- -->111365.

---

Patch is 214.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111416.diff


60 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/GVN.cpp (+14-18) 
- (modified) llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll (+13-6) 
- (modified) llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll (+41-21) 
- (modified) llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll (+29-28) 
- (modified) llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll (+255-142) 
- (modified) llvm/test/Transforms/GVN/2007-07-31-RedundantPhi.ll (+26-8) 
- (modified) llvm/test/Transforms/GVN/2008-02-12-UndefLoad.ll (+18-10) 
- (modified) llvm/test/Transforms/GVN/2008-07-02-Unreachable.ll (+30-13) 
- (modified) llvm/test/Transforms/GVN/2008-12-09-SelfRemove.ll (+25-23) 
- (modified) llvm/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll (+8-3) 
- (modified) llvm/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll (+27-3) 
- (modified) llvm/test/Transforms/GVN/2010-11-13-Simplify.ll (+7-3) 
- (modified) llvm/test/Transforms/GVN/2011-07-07-MatchIntrinsicExtract.ll (+61-18) 
- (modified) llvm/test/Transforms/GVN/2011-09-07-TypeIdFor.ll (+52-8) 
- (modified) llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather-inseltpoison.ll (+21-6) 
- (modified) llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll (+21-6) 
- (modified) llvm/test/Transforms/GVN/assume-equal.ll (+163-66) 
- (modified) llvm/test/Transforms/GVN/basic-undef-test.ll (+9-3) 
- (modified) llvm/test/Transforms/GVN/basic.ll (+7-6) 
- (modified) llvm/test/Transforms/GVN/bitcast-of-call.ll (+11-5) 
- (modified) llvm/test/Transforms/GVN/br-identical.ll (+25-1) 
- (modified) llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll (+1-1) 
- (modified) llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll (+1-1) 
- (modified) llvm/test/Transforms/GVN/calloc-load-removal.ll (+17-6) 
- (modified) llvm/test/Transforms/GVN/calls-nonlocal.ll (+51-49) 
- (modified) llvm/test/Transforms/GVN/calls-readonly.ll (+20-15) 
- (modified) llvm/test/Transforms/GVN/cond_br.ll (+31-6) 
- (modified) llvm/test/Transforms/GVN/cond_br2.ll (+84-8) 
- (modified) llvm/test/Transforms/GVN/dbg-redundant-load.ll (+28-7) 
- (modified) llvm/test/Transforms/GVN/debugloc.ll (+57-6) 
- (modified) llvm/test/Transforms/GVN/edge.ll (+205-45) 
- (modified) llvm/test/Transforms/GVN/fake-use-constprop.ll (+13-3) 
- (modified) llvm/test/Transforms/GVN/flags.ll (+9-5) 
- (modified) llvm/test/Transforms/GVN/fold-const-expr.ll (+11-3) 
- (modified) llvm/test/Transforms/GVN/fpmath.ll (+35-16) 
- (modified) llvm/test/Transforms/GVN/funclet.ll (+24-6) 
- (modified) llvm/test/Transforms/GVN/int_sideeffect.ll (+39-21) 
- (modified) llvm/test/Transforms/GVN/invariant.group.ll (+355-205) 
- (modified) llvm/test/Transforms/GVN/invariant.start.ll (+27-14) 
- (modified) llvm/test/Transforms/GVN/lifetime-simple.ll (+10-3) 
- (modified) llvm/test/Transforms/GVN/load-constant-mem.ll (+13-11) 
- (modified) llvm/test/Transforms/GVN/load-from-unreachable-predecessor.ll (+13-2) 
- (modified) llvm/test/Transforms/GVN/malloc-load-removal.ll (+34-9) 
- (modified) llvm/test/Transforms/GVN/no-mem-dep-info.ll (+12-4) 
- (modified) llvm/test/Transforms/GVN/noalias.ll (+26-12) 
- (modified) llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll (+1-1) 
- (modified) llvm/test/Transforms/GVN/non-local-offset.ll (+29-11) 
- (modified) llvm/test/Transforms/GVN/phi-translate-partial-alias.ll (+13-5) 
- (modified) llvm/test/Transforms/GVN/pr10820.ll (+8-3) 
- (modified) llvm/test/Transforms/GVN/pr12979.ll (+49-26) 
- (modified) llvm/test/Transforms/GVN/pr14166.ll (+10-7) 
- (modified) llvm/test/Transforms/GVN/pr17732.ll (+7-2) 
- (modified) llvm/test/Transforms/GVN/pr24426.ll (+8-1) 
- (modified) llvm/test/Transforms/GVN/pr25440.ll (+76-13) 
- (modified) llvm/test/Transforms/GVN/pr28562.ll (+6-3) 
- (modified) llvm/test/Transforms/GVN/readattrs.ll (+7-3) 
- (modified) llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll (+26-1) 
- (modified) llvm/test/Transforms/GVN/stale-loop-info.ll (+22-1) 
- (modified) llvm/test/Transforms/GVN/tbaa.ll (+72-41) 
- (modified) llvm/test/Transforms/GVN/unreachable-predecessor.ll (+23-8) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 2ba600497e00d3..315ffe4c041a00 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1998,19 +1998,17 @@ static bool impliesEquivalanceIfTrue(CmpInst* Cmp) {
   // +0.0 vs 0.0 for all operators
   if (Cmp->getPredicate() == CmpInst::Predicate::FCMP_OEQ ||
       (Cmp->getPredicate() == CmpInst::Predicate::FCMP_UEQ &&
-       Cmp->getFastMathFlags().noNaNs())) {
+       Cmp->hasNoNaNs())) {
       Value *LHS = Cmp->getOperand(0);
       Value *RHS = Cmp->getOperand(1);
       // If we can prove either side non-zero, then equality must imply
       // equivalence.
-      // FIXME: We should do this optimization if 'no signed zeros' is
-      // applicable via an instruction-level fast-math-flag or some other
-      // indicator that relaxed FP semantics are being used.
-      if (isa<ConstantFP>(LHS) && !cast<ConstantFP>(LHS)->isZero())
-        return true;
-      if (isa<ConstantFP>(RHS) && !cast<ConstantFP>(RHS)->isZero())
-        return true;
-      // TODO: Handle vector floating point constants
+      auto *ConstLHS = dyn_cast<Constant>(LHS),
+           *ConstRHS = dyn_cast<Constant>(RHS);
+      if (auto *Const = ConstLHS ? ConstLHS : ConstRHS) {
+        if (!Const->isZeroValue())
+          return true;
+      }
   }
   return false;
 }
@@ -2023,20 +2021,18 @@ static bool impliesEquivalanceIfFalse(CmpInst* Cmp) {
   // NaNs for unordered operators
   // +0.0 vs 0.0 for all operators
   if ((Cmp->getPredicate() == CmpInst::Predicate::FCMP_ONE &&
-       Cmp->getFastMathFlags().noNaNs()) ||
+       Cmp->hasNoNaNs()) ||
       Cmp->getPredicate() == CmpInst::Predicate::FCMP_UNE) {
       Value *LHS = Cmp->getOperand(0);
       Value *RHS = Cmp->getOperand(1);
       // If we can prove either side non-zero, then equality must imply
       // equivalence.
-      // FIXME: We should do this optimization if 'no signed zeros' is
-      // applicable via an instruction-level fast-math-flag or some other
-      // indicator that relaxed FP semantics are being used.
-      if (isa<ConstantFP>(LHS) && !cast<ConstantFP>(LHS)->isZero())
-        return true;
-      if (isa<ConstantFP>(RHS) && !cast<ConstantFP>(RHS)->isZero())
-        return true;
-      // TODO: Handle vector floating point constants
+      auto *ConstLHS = dyn_cast<Constant>(LHS),
+           *ConstRHS = dyn_cast<Constant>(RHS);
+      if (auto *Const = ConstLHS ? ConstLHS : ConstRHS) {
+        if (!Const->isZeroValue())
+          return true;
+      }
   }
   return false;
 }
diff --git a/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll b/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
index 9c720049bd84a0..9b196eb0a3350e 100644
--- a/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
+++ b/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
@@ -1,15 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 ; RUN: opt < %s -passes=gvn -S | FileCheck %s
 
-	%struct.INT2 = type { i32, i32 }
+%struct.INT2 = type { i32, i32 }
 @blkshifts = external global ptr		; <ptr> [#uses=2]
 
 define i32 @xcompact() {
+; CHECK-LABEL: define i32 @xcompact() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    store ptr null, ptr @blkshifts, align 4
+; CHECK-NEXT:    br label %[[BB:.*]]
+; CHECK:       [[BB]]:
+; CHECK-NEXT:    br label %[[BB]]
+;
 entry:
-	store ptr null, ptr @blkshifts, align 4
-	br label %bb
+  store ptr null, ptr @blkshifts, align 4
+  br label %bb
 
 bb:		; preds = %bb, %entry
-	%tmp10 = load ptr, ptr @blkshifts, align 4		; <ptr> [#uses=0]
-; CHECK-NOT:  %tmp10
-	br label %bb
+  %tmp10 = load ptr, ptr @blkshifts, align 4		; <ptr> [#uses=0]
+  br label %bb
 }
diff --git a/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll b/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
index e8fb8f1087cce9..4c264c1a76d4a6 100644
--- a/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
+++ b/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
@@ -1,40 +1,60 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 ; RUN: opt < %s -passes=gvn -S | FileCheck %s
 
 @last = external global [65 x ptr]
 
 define i32 @NextRootMove(i32 %wtm, i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i32 @NextRootMove(
+; CHECK-SAME: i32 [[WTM:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A:%.*]] = alloca ptr, align 8
+; CHECK-NEXT:    [[TMP17618:%.*]] = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+; CHECK-NEXT:    store ptr [[TMP17618]], ptr [[A]], align 8
+; CHECK-NEXT:    br label %[[COND_TRUE116:.*]]
+; CHECK:       [[COND_TRUE116]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE128:.*]], label %[[COND_TRUE145:.*]]
+; CHECK:       [[COND_TRUE128]]:
+; CHECK-NEXT:    store ptr [[TMP17618]], ptr [[A]], align 8
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[X]], [[Z]]
+; CHECK-NEXT:    br i1 [[CMP1]], label %[[BB98_BACKEDGE:.*]], label %[[RETURN_LOOPEXIT:.*]]
+; CHECK:       [[BB98_BACKEDGE]]:
+; CHECK-NEXT:    br label %[[COND_TRUE116]]
+; CHECK:       [[COND_TRUE145]]:
+; CHECK-NEXT:    store ptr [[TMP17618]], ptr [[A]], align 8
+; CHECK-NEXT:    br i1 false, label %[[COND_TRUE145_BB98_BACKEDGE_CRIT_EDGE:.*]], label %[[RETURN_LOOPEXIT]]
+; CHECK:       [[COND_TRUE145_BB98_BACKEDGE_CRIT_EDGE]]:
+; CHECK-NEXT:    br label %[[BB98_BACKEDGE]]
+; CHECK:       [[RETURN_LOOPEXIT]]:
+; CHECK-NEXT:    ret i32 0
+;
 entry:
-        %A = alloca ptr
-	%tmp17618 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
-        store ptr %tmp17618, ptr %A
-; CHECK: entry:
-; CHECK-NEXT: alloca ptr
-; CHECK-NEXT: %tmp17618 = load
-; CHECK-NOT: load
-; CHECK-NOT: phi
-	br label %cond_true116
+  %A = alloca ptr
+  %tmp17618 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+  store ptr %tmp17618, ptr %A
+  br label %cond_true116
 
 cond_true116:
-   %cmp = icmp eq i32 %x, %y
-	br i1 %cmp, label %cond_true128, label %cond_true145
+  %cmp = icmp eq i32 %x, %y
+  br i1 %cmp, label %cond_true128, label %cond_true145
 
 cond_true128:
-	%tmp17625 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
-        store ptr %tmp17625, ptr %A
-   %cmp1 = icmp eq i32 %x, %z
-	br i1 %cmp1 , label %bb98.backedge, label %return.loopexit
+  %tmp17625 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+  store ptr %tmp17625, ptr %A
+  %cmp1 = icmp eq i32 %x, %z
+  br i1 %cmp1 , label %bb98.backedge, label %return.loopexit
 
 bb98.backedge:
-	br label %cond_true116
+  br label %cond_true116
 
 cond_true145:
-	%tmp17631 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
-        store ptr %tmp17631, ptr %A
-	br i1 false, label %bb98.backedge, label %return.loopexit
+  %tmp17631 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+  store ptr %tmp17631, ptr %A
+  br i1 false, label %bb98.backedge, label %return.loopexit
 
 return.loopexit:
-	br label %return
+  br label %return
 
 return:
-	ret i32 0
+  ret i32 0
 }
diff --git a/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll b/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll
index 6abdc122cd45ff..9fcbd581271a83 100644
--- a/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll
+++ b/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll
@@ -1,44 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 ; RUN: opt < %s -passes=gvn -S | FileCheck %s
 
-	%struct..0anon = type { i32 }
-	%struct.FILE = type { ptr, i32, i32, i16, i16, %struct.__sbuf, i32, ptr, ptr, ptr, ptr, ptr, %struct.__sbuf, ptr, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
-	%struct.__sFILEX = type opaque
-	%struct.__sbuf = type { ptr, i32 }
-	%struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
+%struct..0anon = type { i32 }
+%struct.FILE = type { ptr, i32, i32, i16, i16, %struct.__sbuf, i32, ptr, ptr, ptr, ptr, ptr, %struct.__sbuf, ptr, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+%struct.__sFILEX = type opaque
+%struct.__sbuf = type { ptr, i32 }
+%struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
 @n_spills = external global i32		; <ptr> [#uses=2]
 
 define i32 @reload(ptr %first, i32 %global, ptr %dumpfile) {
+; CHECK-LABEL: define i32 @reload(
+; CHECK-SAME: ptr [[FIRST:%.*]], i32 [[GLOBAL:%.*]], ptr [[DUMPFILE:%.*]]) {
+; CHECK-NEXT:  [[COND_NEXT2835_1:.*:]]
+; CHECK-NEXT:    br label %[[BB2928:.*]]
+; CHECK:       [[BB2928]]:
+; CHECK-NEXT:    br i1 false, label %[[BB2928_COND_NEXT2943_CRIT_EDGE:.*]], label %[[COND_TRUE2935:.*]]
+; CHECK:       [[BB2928_COND_NEXT2943_CRIT_EDGE]]:
+; CHECK-NEXT:    br label %[[COND_NEXT2943:.*]]
+; CHECK:       [[COND_TRUE2935]]:
+; CHECK-NEXT:    br label %[[COND_NEXT2943]]
+; CHECK:       [[COND_NEXT2943]]:
+; CHECK-NEXT:    br i1 false, label %[[BB2982_PREHEADER:.*]], label %[[BB2928]]
+; CHECK:       [[BB2982_PREHEADER]]:
+; CHECK-NEXT:    [[TMP298316:%.*]] = load i32, ptr @n_spills, align 4
+; CHECK-NEXT:    ret i32 [[TMP298316]]
+;
 cond_next2835.1:		; preds = %cond_next2861
-	%tmp2922 = load i32, ptr @n_spills, align 4		; <i32> [#uses=0]
-	br label %bb2928
+  %tmp2922 = load i32, ptr @n_spills, align 4		; <i32> [#uses=0]
+  br label %bb2928
 
 bb2928:		; preds = %cond_next2835.1, %cond_next2943
-	br i1 false, label %cond_next2943, label %cond_true2935
+  br i1 false, label %cond_next2943, label %cond_true2935
 
 cond_true2935:		; preds = %bb2928
-	br label %cond_next2943
+  br label %cond_next2943
 
 cond_next2943:		; preds = %cond_true2935, %bb2928
-	br i1 false, label %bb2982.preheader, label %bb2928
+  br i1 false, label %bb2982.preheader, label %bb2928
 
 bb2982.preheader:		; preds = %cond_next2943
-	%tmp298316 = load i32, ptr @n_spills, align 4		; <i32> [#uses=0]
-	ret i32 %tmp298316
-
+  %tmp298316 = load i32, ptr @n_spills, align 4		; <i32> [#uses=0]
+  ret i32 %tmp298316
 }
 
-; CHECK: define i32 @reload(ptr %first, i32 %global, ptr %dumpfile) {
-; CHECK-NEXT: cond_next2835.1:
-; CHECK-NEXT:   br label %bb2928
-; CHECK: bb2928:
-; CHECK-NEXT:   br i1 false, label %bb2928.cond_next2943_crit_edge, label %cond_true2935
-; CHECK: bb2928.cond_next2943_crit_edge:
-; CHECK-NEXT:   br label %cond_next2943
-; CHECK: cond_true2935:
-; CHECK-NEXT:   br label %cond_next2943
-; CHECK: cond_next2943:
-; CHECK-NEXT:   br i1 false, label %bb2982.preheader, label %bb2928
-; CHECK: bb2982.preheader:
-; CHECK-NEXT:   %tmp298316 = load i32, ptr @n_spills, align 4
-; CHECK-NEXT:   ret i32 %tmp298316
-; CHECK-NEXT: }
diff --git a/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll b/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
index b56ccc128bd6bf..dd94f09a11be23 100644
--- a/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
+++ b/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
@@ -1,6 +1,7 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 ; RUN: opt < %s -passes=gvn -S | FileCheck %s
 
-	%struct.anon = type { ptr, i32, i32, [3 x i32], ptr, ptr, ptr }
+%struct.anon = type { ptr, i32, i32, [3 x i32], ptr, ptr, ptr }
 @debug = external constant i32		; <ptr> [#uses=0]
 @counters = external constant i32		; <ptr> [#uses=1]
 @trialx = external global [17 x i32]		; <ptr> [#uses=1]
@@ -133,182 +134,294 @@ declare i32 @increment()
 declare i32 @search()
 
 define i32 @main(i32 %argc, ptr %argv) {
+; CHECK-LABEL: define i32 @main(
+; CHECK-SAME: i32 [[ARGC:%.*]], ptr [[ARGV:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[ARGC_ADDR:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[ARGV_ADDR:%.*]] = alloca ptr, align 8
+; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[NUM_SOL:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[TOTAL:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    store i32 [[ARGC]], ptr [[ARGC_ADDR]], align 4
+; CHECK-NEXT:    store ptr [[ARGV]], ptr [[ARGV_ADDR]], align 8
+; CHECK-NEXT:    store i32 0, ptr [[NUM_SOL]], align 4
+; CHECK-NEXT:    store i32 1, ptr @numi, align 4
+; CHECK-NEXT:    br label %[[BB91:.*]]
+; CHECK:       [[BB:.*]]:
+; CHECK-NEXT:    [[TMP3:%.*]] = call i32 (ptr, ...) @printf(ptr @.str43, i32 [[TMP1:%.*]])
+; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+; CHECK-NEXT:    br label %[[BB13:.*]]
+; CHECK:       [[BB4:.*]]:
+; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr [17 x i32], ptr @trialx, i32 0, i32 [[TMP11:%.*]]
+; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
+; CHECK-NEXT:    [[TMP9:%.*]] = call i32 @userfun(i32 [[TMP8]])
+; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr [17 x i32], ptr @correct_result, i32 0, i32 [[TMP11]]
+; CHECK-NEXT:    store i32 [[TMP9]], ptr [[TMP10]], align 4
+; CHECK-NEXT:    [[TMP12:%.*]] = add i32 [[TMP11]], 1
+; CHECK-NEXT:    store i32 [[TMP12]], ptr [[I]], align 4
+; CHECK-NEXT:    br label %[[BB13]]
+; CHECK:       [[BB13]]:
+; CHECK-NEXT:    [[TMP11]] = phi i32 [ [[TMP12]], %[[BB4]] ], [ 0, %[[BB]] ]
+; CHECK-NEXT:    [[TMP15:%.*]] = icmp sle i32 [[TMP11]], 16
+; CHECK-NEXT:    [[TMP1516:%.*]] = zext i1 [[TMP15]] to i32
+; CHECK-NEXT:    br i1 [[TMP15]], label %[[BB4]], label %[[BB17:.*]]
+; CHECK:       [[BB17]]:
+; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+; CHECK-NEXT:    br label %[[BB49:.*]]
+; CHECK:       [[BB18:.*]]:
+; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 [[TMP47:%.*]]
+; CHECK-NEXT:    store i32 0, ptr [[TMP20]], align 4
+; CHECK-NEXT:    [[TMP26:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @isa, i64 16), align 4
+; CHECK-NEXT:    [[TMP28:%.*]] = getelementptr { i32, [3 x i32] }, ptr [[TMP20]], i32 0, i32 1
+; CHECK-NEXT:    store i32 [[TMP26]], ptr [[TMP28]], align 4
+; CHECK-NEXT:    [[TMP34:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @isa, i64 20), align 4
+; CHECK-NEXT:    [[TMP37:%.*]] = getelementptr [3 x i32], ptr [[TMP28]], i32 0, i32 1
+; CHECK-NEXT:    store i32 [[TMP34]], ptr [[TMP37]], align 4
+; CHECK-NEXT:    [[TMP42:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @isa, i64 24), align 4
+; CHECK-NEXT:    [[TMP45:%.*]] = getelementptr [3 x i32], ptr [[TMP28]], i32 0, i32 2
+; CHECK-NEXT:    store i32 [[TMP42]], ptr [[TMP45]], align 4
+; CHECK-NEXT:    call void @fix_operands(i32 [[TMP47]])
+; CHECK-NEXT:    [[TMP48:%.*]] = add i32 [[TMP47]], 1
+; CHECK-NEXT:    store i32 [[TMP48]], ptr [[I]], align 4
+; CHECK-NEXT:    br label %[[BB49]]
+; CHECK:       [[BB49]]:
+; CHECK-NEXT:    [[TMP47]] = phi i32 [ [[TMP48]], %[[BB18]] ], [ 0, %[[BB17]] ]
+; CHECK-NEXT:    [[TMP50:%.*]] = load i32, ptr @numi, align 4
+; CHECK-NEXT:    [[TMP52:%.*]] = icmp slt i32 [[TMP47]], [[TMP50]]
+; CHECK-NEXT:    [[TMP5253:%.*]] = zext i1 [[TMP52]] to i32
+; CHECK-NEXT:    br i1 [[TMP52]], label %[[BB18]], label %[[BB55:.*]]
+; CHECK:       [[BB55]]:
+; CHECK-NEXT:    [[TMP56:%.*]] = call i32 @search()
+; CHECK-NEXT:    store i32 [[TMP56]], ptr [[NUM_SOL]], align 4
+; CHECK-NEXT:    [[TMP59:%.*]] = call i32 (ptr, ...) @printf(ptr @.str44, i32 [[TMP56]])
+; CHECK-NEXT:    [[TMP60:%.*]] = load i32, ptr @counters, align 4
+; CHECK-NEXT:    [[TMP61:%.*]] = icmp ne i32 [[TMP60]], 0
+; CHECK-NEXT:    [[TMP6162:%.*]] = zext i1 [[TMP61]] to i32
+; CHECK-NEXT:    br i1 [[TMP61]], label %[[COND_TRUE:.*]], label %[[COND_NEXT:.*]]
+; CHECK:       [[COND_TRUE]]:
+; CHECK-NEXT:    store i32 0, ptr [[TOTAL]], align 4
+; CHECK-NEXT:    [[TMP65:%.*]] = call i32 (ptr, ...) @printf(ptr @.str45)
+; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+; CHECK-NEXT:    br label %[[BB79:.*]]
+; CHECK:       [[BB66:.*]]:
+; CHECK-NEXT:    [[TMP68:%.*]] = getelementptr [5 x i32], ptr @counter, i32 0, i32 [[TMP77:%.*]]
+; CHECK-NEXT:    [[TMP69:%.*]] = load i32, ptr [[TMP68]], align 4
+; CHECK-NEXT:    [[TMP71:%.*]] = call i32 (ptr, ...) @printf(ptr @.str46, i32 [[TMP69]])
+; CHECK-NEXT:    [[TMP74:%.*]] = load i32, ptr [[TMP68]], align 4
+; CHECK-NEXT:    [[TMP76:%.*]] = add i32 [[TMP74]], [[TMP75:%.*]]
+; CHECK-NEXT:    store i32 [[TMP76]], ptr [[TOTAL]], align 4
+; CHECK-NEXT:    [[TMP78:%.*]] = add i32 [[TMP77]], 1
+; CHECK-NEXT:    store i32 [[TMP78]], ptr [[I]], align 4
+; CHECK-NEXT:    br label %[[BB79]]
+; CHECK:       [[BB79]]:
+; CHECK-NEXT:    [[TMP75]] = phi i32 [ [[TMP76]], %[[BB66]] ], [ 0, %[[COND_TRUE]] ]
+; CHECK-NEXT:    [[TMP77]] = phi i32 [ [[TMP78]], %[[BB66]] ], [ 0, %[[COND_TRUE]] ]
+; CHECK-NEXT:    [[TMP80:%.*]] = load i32, ptr @numi, align 4
+; CHECK-NEXT:    [[TMP82:%.*]] = icmp slt i32 [[TMP77]], [[TMP80]]
+; CHECK-NEXT:    [[TMP8283:%.*]] = zext i1 [[TMP82]] to i32
+; CHECK-NEXT:    br i1 [[TMP82]], label %[[BB66]], label %[[BB85:.*]]
+; CHECK:       [[BB85]]:
+; CHECK-NEXT:    [[TMP88:%.*]] = call i32 (ptr, ...) @printf(ptr @.str47, i32 [[TMP75]])
+; CHECK-NEXT:    br label %[[COND_NEXT]]
+; CHECK:       [[COND_NEXT]]:
+; CHECK-NEXT:    [[TMP89:%.*]] = load i32, ptr @numi, align 4
+; CHECK-NEXT:    [[TMP90:%.*]] = add i32 [[TMP89]], 1
+; CHECK-NEXT:    store i32 [[TMP90]], ptr @numi, align 4
+; CHECK-NEXT:    br label %[[BB91]]
+; CHECK:       [[BB91]]:
+; CHECK-NEXT:    [[TMP98:%.*]] = phi i32 [ [[TMP56]], %[[COND_NEXT]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT:    [[TMP1]] = phi i32 [ [[TMP90]], %[[COND_NEXT]] ], [ 1, %[[ENTRY]] ]
+; CHECK-NEXT:    [[TMP93:%.*]] = icmp sgt i32 [[TMP1]], 5
+; CHECK-NEXT:    [[TMP9394:%.*]] = zext i1 [[TMP93]] to i32
+; CHECK-NEXT:    br i1 [[TMP93]], label %[[COND_TRUE96:.*]], label %[[COND_NEXT97:.*]]
+; CHECK:       [[COND_TRUE96]]:
+; CHECK-NEXT:    br label %[[BB102:.*]]
+; CHECK:       [[COND_NEXT97]]:
+; CHECK-NEXT:    [[TMP99:%.*]] = icmp eq i32 [[TMP98]], 0
+; CHECK-NEXT:    [[TMP99100:%.*]] = zext i1 [[TMP99]] to i32
+; CHECK-NEXT:    br i1 [[TMP99]], label %[[BB]], label %[[BB102]]
+; CHECK:       [[BB102]]:
+; CHECK-NEXT:    store i32 0, ptr [[TMP]], align 4
+; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 0
+;
 entry:
-	%argc_addr = alloca i32		; <ptr> [#uses=1]
-	%argv_addr = alloca ptr		; <ptr> [#uses=1]
-	%retval = alloca i32, align 4		; <ptr> [#uses=2]
-	%tmp = alloca i32, align 4		; <ptr> [#uses=2]
-	%i = alloca i32, align 4		; <ptr> [#uses=21]
-	%num_sol = alloca i32, align 4		; <ptr> [#uses=4]
-	%total = alloca i32, align 4		; <ptr> [#uses=4]
-	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
-	store i32 %argc, ptr %argc_addr
-	store ptr %argv, ptr %argv_addr
-	store i32 0, ptr %num_sol
-	store i32 1, ptr @numi
-	br label %bb91
+  %argc_addr = alloca i32		; <ptr> [#uses=1]
+  %argv_addr = alloca ptr		; <ptr> [#uses=1]
+  %retval = alloca i32, align 4		; <ptr> [#uses=2]
+  %tmp = alloca i32, align 4		; <ptr> [#uses=2]
+  %i = alloca i32, align 4		; <ptr> [#uses=21]
+  %num_sol = alloca i32, align 4		; <ptr> [#uses=4]
+  %total = alloca i32, align 4		; <ptr> [#uses=4]
+  %"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+  store i32 %argc, ptr %argc_addr
+  store ptr %argv, ptr %argv_addr
+  store i32 0, ptr %num_sol
+  store i32 1, ptr @numi
+  br label %bb91
 
 bb:		; preds = %cond_next97
-	%tmp1 = load i32, ptr @numi		; <i32> [#uses=1]
-	%tmp2 = getelementptr [44 x i8], ptr @.str43, i32 0, i32 0		; <ptr> [#uses=1]
-	%tmp3 = call i32 (ptr, ...) @printf( ptr %tmp2, i32 %tmp1 )		; <i32> [#uses=0]
-	store i32 0, ptr %i
-	br label %bb13
+  %tmp1 = load i32, ptr @numi		; <i32> [#uses=1]
+  %tmp2 = getelementptr [44 x i8], ptr @.str43, i32 0, i32 0		; <ptr> [#uses=1]
+  %tmp3 = call i32 (ptr, ...) @printf( ptr %tmp2, i32 %tmp1 )		; <i32> [#uses=0]
+  store i32 0, ptr %i
+  br label %bb13
 
 bb4:		; preds = %bb13
-	%tmp5 = load i32, ptr %i		; <i32> [#uses=1]
-	%tmp6 = load i32, ptr %i		; <i32> [#uses=1]
-	%tmp7 = getelementptr [17 x i32], ptr @trialx, i32 0, i32 %tmp6		; <ptr> [#uses=1]
-	%tmp8 = load i32, ptr %tmp7		; <i32> [#uses=1]
-	%tmp9 = call i32 @userfun( i32 %tmp8 )		; <i32> [#uses=1]
-	%tmp10 = getelementptr [17 x i32], ptr @correct_result, i32 0, i32 %tmp5		; <ptr> [#uses=1]
-	store i32 %tmp9, ptr %tmp10
-	%tmp11 = load i32, ptr %i		; <i32> [#uses=1]
-	%tmp12 = add i32 %tmp11, 1		; <i32> [#uses=1]
-	store i32 %tmp12, ptr %i
-	br label %bb13
+  %tmp5 = load i32, ptr ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/111416


More information about the llvm-commits mailing list