1; RUN: opt < %s -passes=jump-threading -S | FileCheck %s 2 3; Skip simplifying unconditional branches from empty blocks in simplifyCFG, 4; when it can destroy canonical loop structure. 5 6; void foo(); 7; bool test(int a, int b, int *c) { 8; bool changed = false; 9; for (unsigned int i = 2; i--;) { 10; int r = a | b; 11; if ( r != c[i]) { 12; c[i] = r; 13; foo(); 14; changed = true; 15; } 16; } 17; return changed; 18; } 19 20; CHECK-LABEL: @test( 21; CHECK: for.cond: 22; CHECK-NEXT: %i.0 = phi i32 [ 2, %entry ], [ %dec, %if.end ] 23; CHECK: for.body: 24; CHECK: br i1 %cmp, label %if.end, label %if.then 25; CHECK-NOT: br i1 %cmp, label %for.cond, label %if.then 26; CHECK: if.then: 27; CHECK: br label %if.end 28; CHECK-NOT: br label %for.cond 29; CHECK: if.end: 30; CHECK: br label %for.cond 31define i1 @test(i32 %a, i32 %b, ptr %c) { 32entry: 33 br label %for.cond 34 35for.cond: ; preds = %if.end, %entry 36 %i.0 = phi i32 [ 2, %entry ], [ %dec, %if.end ] 37 %changed.0.off0 = phi i1 [ false, %entry ], [ %changed.1.off0, %if.end ] 38 %dec = add nsw i32 %i.0, -1 39 %tobool = icmp eq i32 %i.0, 0 40 br i1 %tobool, label %for.cond.cleanup, label %for.body 41 42for.cond.cleanup: ; preds = %for.cond 43 %changed.0.off0.lcssa = phi i1 [ %changed.0.off0, %for.cond ] 44 ret i1 %changed.0.off0.lcssa 45 46for.body: ; preds = %for.cond 47 %or = or i32 %a, %b 48 %idxprom = sext i32 %dec to i64 49 %arrayidx = getelementptr inbounds i32, ptr %c, i64 %idxprom 50 %0 = load i32, ptr %arrayidx, align 4 51 %cmp = icmp eq i32 %or, %0 52 br i1 %cmp, label %if.end, label %if.then 53 54if.then: ; preds = %for.body 55 store i32 %or, ptr %arrayidx, align 4 56 call void @foo() 57 br label %if.end 58 59if.end: ; preds = %for.body, %if.then 60 %changed.1.off0 = phi i1 [ true, %if.then ], [ %changed.0.off0, %for.body ] 61 br label %for.cond 62} 63 64declare void @foo() 65