190 lines · plain
1; RUN: opt < %s -passes="jump-threading,print<lazy-value-info>" -disable-output 2>&1 | FileCheck %s2 3; Testing LVI cache after jump-threading4 5; Jump-threading transforms the IR below to one where6; 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, 4009; br i1 %cont, label %backedge, label %exit10define 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: overdefined15; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined16 br label %loop17 18; CHECK-LABEL: backedge:19; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined20; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined21; 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, 127; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined28; 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, 40030; CHECK-NOT: loop31loop:32 %iv = phi i32 [0, %entry], [%iv.next, %backedge]33 %cnd = icmp sge i32 %iv, 034 br i1 %cnd, label %backedge, label %exit35 36backedge:37 %iv.next = add nsw i32 %iv, 138 %cont = icmp slt i32 %iv.next, 40039 br i1 %cont, label %loop, label %exit40 41exit:42 ret i8 043}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: overdefined50; CHECK-NEXT: br label %loop51entry:52 br label %loop53 54; CHECK-LABEL: loop:55; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined56; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange<0, 400>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, -2147483648>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: overdefined63; 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: overdefined65; 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: overdefined69; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%backedge' is: overdefined70; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%exit' is: overdefined71; CHECK-NEXT: %cnd1 = icmp sge i32 %iv, 072 %cnd1 = icmp sge i32 %iv, 073 %cnd2 = icmp sgt i32 %iv2, 074; CHECK: %cnd2 = icmp sgt i32 %iv2, 075; CHECK: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%loop' is: overdefined76; 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: overdefined78; CHECK-NEXT: %cnd = and i1 %cnd1, %cnd279 %cnd = and i1 %cnd1, %cnd280 br i1 %cnd, label %backedge, label %exit81 82; CHECK-LABEL: backedge:83; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined84; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, -2147483648>85; CHECK-NEXT: %iv.next = add nsw i32 %iv, 186backedge:87 %iv.next = add nsw i32 %iv, 188 %iv2.next = sub nsw i32 %iv2, 189; CHECK: ; LatticeVal for: ' %cont1 = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined90; CHECK-NEXT: %cont1 = icmp slt i32 %iv.next, 40091 %cont1 = icmp slt i32 %iv.next, 40092; CHECK-NEXT: ; LatticeVal for: ' %cont2 = icmp sgt i32 %iv2.next, 0' in BB: '%backedge' is: overdefined93; CHECK-NEXT: %cont2 = icmp sgt i32 %iv2.next, 094 %cont2 = icmp sgt i32 %iv2.next, 095; CHECK-NEXT: ; LatticeVal for: ' %cont = and i1 %cont1, %cont2' in BB: '%backedge' is: overdefined96; CHECK-NEXT: %cont = and i1 %cont1, %cont297 %cont = and i1 %cont1, %cont298 br i1 %cont, label %loop, label %exit99 100exit:101 ret i8 0102}103 104; Merging cont block into do block. Make sure that we do not incorrectly have the cont105; 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: entry110; CHECK: ; LatticeVal for: 'i32 %i' is: overdefined111; CHECK: %c = icmp ne i32 %i, -2134112; CHECK: br i1 %c, label %cont, label %exit113entry:114 %c = icmp ne i32 %i, -2134115 br i1 %c, label %do, label %exit116 117exit:118 %c1 = icmp ne i32 %i, -42119 br i1 %c1, label %exit2, label %exit120 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: overdefined127; CHECK: %cond.0 = icmp sgt i32 %i, 0128; CHECK: %consume = call i32 @consume129; CHECK: %cond = icmp eq i32 %i, 0130; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond)131; CHECK: %cond.3 = icmp sgt i32 %i, %n132; CHECK: br i1 %cond.3, label %exit2, label %exit133cont:134 %cond.3 = icmp sgt i32 %i, %n135 br i1 %cond.3, label %exit2, label %exit136 137do:138 %cond.0 = icmp sgt i32 %i, 0139 %consume = call i32 @consume(i1 %cond.0)140 %cond = icmp eq i32 %i, 0141 call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]142 %cond.2 = icmp sgt i32 %i, 0143 br i1 %cond.2, label %exit, label %cont144 145exit2:146; CHECK-LABEL: exit2:147; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1>148 ret i32 30149}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, -2134157 br i1 %c, label %do, label %exit158 159exit: ; preds = %do, %cont, %exit, %entry160 %c1 = icmp ne i32 %i, -42161 br i1 %c1, label %exit2, label %exit162 163cont: ; preds = %do164; 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 %exit2169 170do: ; preds = %entry171; CHECK-LABEL: do:172; CHECK: ; LatticeVal for: 'i1 %f' is: overdefined173; CHECK: call void @dummy(i1 %f)174; CHECK: br i1 %cond, label %exit, label %cont175 call void @dummy(i1 %f)176 %consume = call i32 @exit()177 call void @llvm.assume(i1 %f)178 %cond = icmp eq i1 %f, false179 br i1 %cond, label %exit, label %cont180 181exit2: ; preds = %cont, %exit182 ret i32 30183}184 185declare i32 @exit()186declare i32 @consume(i1)187declare void @llvm.assume(i1) nounwind188declare void @dummy(i1) nounwind189declare void @llvm.experimental.guard(i1, ...)190