Add tests from D93882
This patch adds tests from 's Alive2 links.
The tests have src/tgt functions where tgt has llvm.assume calls introduced to show that the exit value of i should/shouldn't be min/max of n, m.
ADD
tests/alive-tv/loops/scev-exactnottaken.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; exact-not-taken cannot be umin(n, m) because it is possible for (n, m) to be (0, poison)
+
+define void @src(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, %n
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond_and = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond_and, label %loop, label %exit
+exit:
+ ret void
+}
+
+define void @tgt(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, %n
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond_and = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond_and, label %loop, label %exit
+exit:
+ %n_m_min = call i32 @llvm.umin.i32(i32 %n, i32 %m)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_min
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+; ERROR: Source is more defined than target
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umin.i32(i32, i32)

ADD
tests/alive-tv/loops/scev-exactnottaken2.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; If m is constant, exact-not-taken is umin(n, m)
+
+define void @src(i32 %n) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, %n
+ %cond_i2 = icmp ult i32 %i, 2
+ %cond = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond, label %loop, label %exit
+exit:
+ ret void
+}
+
+define void @tgt(i32 %n) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, %n
+ %cond_i2 = icmp ult i32 %i, 2
+ %cond = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond, label %loop, label %exit
+exit:
+ %n_m_min = call i32 @llvm.umin.i32(i32 %n, i32 2)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_min
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umin.i32(i32, i32)

ADD
tests/alive-tv/loops/scev-exactnottaken3.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; exact-not-taken is umin(2, m) because m participates in the exit branch condition.
+
+define void @src(i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, 2
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond, label %loop, label %exit
+exit:
+ ret void
+}
+
+define void @tgt(i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, 2
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond, label %loop, label %exit
+exit:
+ %n_m_min = call i32 @llvm.umin.i32(i32 2, i32 %m)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_min
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umin.i32(i32, i32)

ADD
tests/alive-tv/loops/scev-exactnottaken4.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; exact-not-taken cannot be umin(0, m) because m never participates in the exit branch condition.
+; Instead, ExactNotTaken should be just 0.
+
+define void @src(i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, 0
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond, label %loop, label %exit
+exit:
+ ret void
+}
+
+define void @tgt(i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, 0
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond, label %loop, label %exit
+exit:
+ %n_m_min = call i32 @llvm.umin.i32(i32 0, i32 %m)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_min
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+; ERROR: Source is more defined than target
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umin.i32(i32, i32)

ADD
tests/alive-tv/loops/scev-exactnottaken5.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; exact-not-taken is umax(n, m) because both conditions (cond_i, cond_i2) participate in branching,
+; preventing them from being poison.
+
+define void @src(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp uge i32 %i, %n
+ %cond_i2 = icmp uge i32 %i, %m
+ %cond_and = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond_and, label %exit, label %loop
+exit:
+ ret void
+}
+
+define void @tgt(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp uge i32 %i, %n
+ %cond_i2 = icmp uge i32 %i, %m
+ %cond_and = select i1 %cond_i, i1 %cond_i2, i1 false
+ br i1 %cond_and, label %exit, label %loop
+exit:
+ %n_m_max = call i32 @llvm.umax.i32(i32 %n, i32 %m)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_max
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umax.i32(i32, i32)

ADD
tests/alive-tv/loops/scev-exactnottaken6.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; exact-not-taken cannot be umin(n, m) because it is possible for (n, m) to be (0, poison)
+
+define void @src(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp uge i32 %i, %n
+ %cond_i2 = icmp uge i32 %i, %m
+ %cond_or = select i1 %cond_i, i1 true, i1 %cond_i2
+ br i1 %cond_or, label %exit, label %loop
+exit:
+ ret void
+}
+
+define void @tgt(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp uge i32 %i, %n
+ %cond_i2 = icmp uge i32 %i, %m
+ %cond_or = select i1 %cond_i, i1 true, i1 %cond_i2
+ br i1 %cond_or, label %exit, label %loop
+exit:
+ %n_m_min = call i32 @llvm.umin.i32(i32 %n, i32 %m)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_min
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+; ERROR: Source is more defined than target
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umin.i32(i32, i32)

ADD
tests/alive-tv/loops/scev-exactnottaken7.srctgt.ll
+; TEST-ARGS: -src-unroll=3 -tgt-unroll=3
+; https://reviews.llvm.org/D93882
+; exact-not-taken is umax(n, m) because both conditions (cond_i, cond_i2) participate in branching,
+; preventing them from being poison.
+
+define void @src(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, %n
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond_or = select i1 %cond_i, i1 true, i1 %cond_i2
+ br i1 %cond_or, label %loop, label %exit
+exit:
+ ret void
+}
+
+define void @tgt(i32 %n, i32 %m) {
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [0, %entry], [%i.next, %loop]
+ %i.next = add i32 %i, 1
+ %cond_i = icmp ult i32 %i, %n
+ %cond_i2 = icmp ult i32 %i, %m
+ %cond_or = select i1 %cond_i, i1 true, i1 %cond_i2
+ br i1 %cond_or, label %loop, label %exit
+exit:
+ %n_m_max = call i32 @llvm.umax.i32(i32 %n, i32 %m)
+ %ExactNotTaken = icmp eq i32 %i, %n_m_max
+ call void @llvm.assume(i1 %ExactNotTaken)
+ ret void
+}
+
+declare void @llvm.assume(i1)
+declare i32 @llvm.umax.i32(i32, i32)

Add tests from D93882 (#641)

This patch adds tests from https://reviews.llvm.org/D93882 's Alive2 links.

The tests have src/tgt functions where tgt has llvm.assume calls introduced to show that the exit value of i should/shouldn't be min/max of n, m.