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 10define i8 @test1(i32 %a, i32 %length) { 11; CHECK-LABEL: LVI for function 'test1': 12entry: 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 31loop: 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 36backedge: 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 41exit: 42 ret i8 0 43} 44 45; Here JT does not transform the code, but LVICache is populated during the processing of blocks. 46define 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 51entry: 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 ] 60loop: 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 86backedge: 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 100exit: 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. 107define 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 113entry: 114 %c = icmp ne i32 %i, -2134 115 br i1 %c, label %do, label %exit 116 117exit: 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 133cont: 134 %cond.3 = icmp sgt i32 %i, %n 135 br i1 %cond.3, label %exit2, label %exit 136 137do: 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 145exit2: 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. 153define i32 @test4(i32 %i, i1 %f, i32 %n) { 154; CHECK-LABEL: LVI for function 'test4': 155entry: 156 %c = icmp ne i32 %i, -2134 157 br i1 %c, label %do, label %exit 158 159exit: ; preds = %do, %cont, %exit, %entry 160 %c1 = icmp ne i32 %i, -42 161 br i1 %c1, label %exit2, label %exit 162 163cont: ; 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 170do: ; 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 181exit2: ; preds = %cont, %exit 182 ret i32 30 183} 184 185declare i32 @exit() 186declare i32 @consume(i1) 187declare void @llvm.assume(i1) nounwind 188declare void @dummy(i1) nounwind 189declare void @llvm.experimental.guard(i1, ...) 190