1 ; RUN: opt < %s -jump-threading -print-lvi-after-jump-threading -disable-output 2>&1 | FileCheck %s 2 3 ; Testing LVI cache after jump-threading 4 5 ; Jump-threading transforms the IR below to one where 6 ; loop and backedge basic blocks are merged into one. 7 ; basic block (named backedge) with the branch being: 8 ; %cont = icmp slt i32 %iv.next, 400 9 ; br i1 %cont, label %backedge, label %exit 10 define i8 @test1(i32 %a, i32 %length) { 11 ; CHECK-LABEL: LVI for function 'test1': 12 entry: 13 ; CHECK-LABEL: entry: 14 ; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined 15 ; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined 16 br label %loop 17 18 ; CHECK-LABEL: backedge: 19 ; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined 20 ; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined 21 ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400> 22 ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<399, 400> 23 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 24 ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, 401> 25 ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%exit' is: constantrange<400, 401> 26 ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 27 ; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined 28 ; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%exit' is: constantrange<0, -1> 29 ; CHECK-NEXT: %cont = icmp slt i32 %iv.next, 400 30 ; CHECK-NOT: loop 31 loop: 32 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 33 %cnd = icmp sge i32 %iv, 0 34 br i1 %cnd, label %backedge, label %exit 35 36 backedge: 37 %iv.next = add nsw i32 %iv, 1 38 %cont = icmp slt i32 %iv.next, 400 39 br i1 %cont, label %loop, label %exit 40 41 exit: 42 ret i8 0 43 } 44 45 ; Here JT does not transform the code, but LVICache is populated during the processing of blocks. 46 define i8 @test2(i32 %n) { 47 ; CHECK-LABEL: LVI for function 'test2': 48 ; CHECK-LABEL: entry: 49 ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined 50 ; CHECK-NEXT: br label %loop 51 entry: 52 br label %loop 53 54 ; CHECK-LABEL: loop: 55 ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined 56 ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange<0, -2147483647> 57 ; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, -2147483648> 58 ; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<0, -2147483647> 59 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] 60 loop: 61 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 62 ; CHECK-NEXT: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%loop' is: overdefined 63 ; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%backedge' is: constantrange<1, -2147483648> 64 ; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%exit' is: overdefined 65 ; CHECK-NEXT: %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ] 66 %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge] 67 68 ; CHECK-NEXT: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%loop' is: overdefined 69 ; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%backedge' is: overdefined 70 ; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%exit' is: overdefined 71 ; CHECK-NEXT: %cnd1 = icmp sge i32 %iv, 0 72 %cnd1 = icmp sge i32 %iv, 0 73 %cnd2 = icmp sgt i32 %iv2, 0 74 ; CHECK: %cnd2 = icmp sgt i32 %iv2, 0 75 ; CHECK: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%loop' is: overdefined 76 ; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%backedge' is: constantrange<-1, 0> 77 ; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%exit' is: overdefined 78 ; CHECK-NEXT: %cnd = and i1 %cnd1, %cnd2 79 %cnd = and i1 %cnd1, %cnd2 80 br i1 %cnd, label %backedge, label %exit 81 82 ; CHECK-LABEL: backedge: 83 ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined 84 ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, -2147483647> 85 ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 86 backedge: 87 %iv.next = add nsw i32 %iv, 1 88 %iv2.next = sub nsw i32 %iv2, 1 89 ; CHECK: ; LatticeVal for: ' %cont1 = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined 90 ; CHECK-NEXT: %cont1 = icmp slt i32 %iv.next, 400 91 %cont1 = icmp slt i32 %iv.next, 400 92 ; CHECK-NEXT: ; LatticeVal for: ' %cont2 = icmp sgt i32 %iv2.next, 0' in BB: '%backedge' is: overdefined 93 ; CHECK-NEXT: %cont2 = icmp sgt i32 %iv2.next, 0 94 %cont2 = icmp sgt i32 %iv2.next, 0 95 ; CHECK-NEXT: ; LatticeVal for: ' %cont = and i1 %cont1, %cont2' in BB: '%backedge' is: overdefined 96 ; CHECK-NEXT: %cont = and i1 %cont1, %cont2 97 %cont = and i1 %cont1, %cont2 98 br i1 %cont, label %loop, label %exit 99 100 exit: 101 ret i8 0 102 } 103 104 ; Merging cont block into do block. Make sure that we do not incorrectly have the cont 105 ; LVI info as LVI info for the beginning of do block. LVI info for %i is Range[0,1) 106 ; at beginning of cont Block, which is incorrect at the beginning of do block. 107 define i32 @test3(i32 %i, i1 %f, i32 %n) { 108 ; CHECK-LABEL: LVI for function 'test3': 109 ; CHECK-LABEL: entry 110 ; CHECK: ; LatticeVal for: 'i32 %i' is: overdefined 111 ; CHECK: %c = icmp ne i32 %i, -2134 112 ; CHECK: br i1 %c, label %cont, label %exit 113 entry: 114 %c = icmp ne i32 %i, -2134 115 br i1 %c, label %do, label %exit 116 117 exit: 118 %c1 = icmp ne i32 %i, -42 119 br i1 %c1, label %exit2, label %exit 120 121 ; CHECK-LABEL: cont: 122 ; Here cont is merged to do and i is any value except -2134. 123 ; i is not the single value: zero. 124 ; CHECK-NOT: ; LatticeVal for: 'i32 %i' is: constantrange<0, 1> 125 ; CHECK: ; LatticeVal for: 'i32 %i' is: constantrange<-2133, -2134> 126 ; CHECK: ; LatticeVal for: ' %cond.0 = icmp sgt i32 %i, 0' in BB: '%cont' is: overdefined 127 ; CHECK: %cond.0 = icmp sgt i32 %i, 0 128 ; CHECK: %consume = call i32 @consume 129 ; CHECK: %cond = icmp eq i32 %i, 0 130 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond) 131 ; CHECK: %cond.3 = icmp sgt i32 %i, %n 132 ; CHECK: br i1 %cond.3, label %exit2, label %exit 133 cont: 134 %cond.3 = icmp sgt i32 %i, %n 135 br i1 %cond.3, label %exit2, label %exit 136 137 do: 138 %cond.0 = icmp sgt i32 %i, 0 139 %consume = call i32 @consume(i1 %cond.0) 140 %cond = icmp eq i32 %i, 0 141 call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] 142 %cond.2 = icmp sgt i32 %i, 0 143 br i1 %cond.2, label %exit, label %cont 144 145 exit2: 146 ; CHECK-LABEL: exit2: 147 ; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1> 148 ret i32 30 149 } 150 151 ; FIXME: We should be able to merge cont into do. 152 ; When we do so, LVI for cont cannot be the one for the merged do block. 153 define i32 @test4(i32 %i, i1 %f, i32 %n) { 154 ; CHECK-LABEL: LVI for function 'test4': 155 entry: 156 %c = icmp ne i32 %i, -2134 157 br i1 %c, label %do, label %exit 158 159 exit: ; preds = %do, %cont, %exit, %entry 160 %c1 = icmp ne i32 %i, -42 161 br i1 %c1, label %exit2, label %exit 162 163 cont: ; preds = %do 164 ; CHECK-LABEL: cont: 165 ; CHECK: ; LatticeVal for: 'i1 %f' is: constantrange<-1, 0> 166 ; CHECK: call void @dummy(i1 %f) 167 call void @dummy(i1 %f) 168 br label %exit2 169 170 do: ; preds = %entry 171 ; CHECK-LABEL: do: 172 ; CHECK: ; LatticeVal for: 'i1 %f' is: overdefined 173 ; CHECK: call void @dummy(i1 %f) 174 ; CHECK: br i1 %cond, label %exit, label %cont 175 call void @dummy(i1 %f) 176 %consume = call i32 @exit() 177 call void @llvm.assume(i1 %f) 178 %cond = icmp eq i1 %f, false 179 br i1 %cond, label %exit, label %cont 180 181 exit2: ; preds = %cont, %exit 182 ret i32 30 183 } 184 185 declare i32 @exit() 186 declare i32 @consume(i1) 187 declare void @llvm.assume(i1) nounwind 188 declare void @dummy(i1) nounwind 189 declare void @llvm.experimental.guard(i1, ...) 190