1; RUN: opt -correlated-propagation -S < %s | FileCheck %s 2 3declare void @llvm.experimental.guard(i1,...) 4 5define i1 @test1(i32 %a) { 6; CHECK-LABEL: @test1( 7; CHECK: %alive = icmp eq i32 %a, 8 8; CHECK-NEXT: %result = or i1 false, %alive 9 %cmp = icmp ult i32 %a, 16 10 call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 11 %dead = icmp eq i32 %a, 16 12 %alive = icmp eq i32 %a, 8 13 %result = or i1 %dead, %alive 14 ret i1 %result 15} 16 17define i1 @test2(i32 %a) { 18; CHECK-LABEL: @test2( 19; CHECK: continue: 20; CHECK-NEXT: %alive = icmp eq i32 %a, 8 21; CHECK-NEXT: %result = or i1 false, %alive 22 %cmp = icmp ult i32 %a, 16 23 call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 24 br label %continue 25 26continue: 27 %dead = icmp eq i32 %a, 16 28 %alive = icmp eq i32 %a, 8 29 %result = or i1 %dead, %alive 30 ret i1 %result 31} 32 33define i1 @test3(i32 %a, i1 %flag) { 34; CHECK-LABEL: @test3( 35; CHECK: continue: 36; CHECK-NEXT: %alive.1 = icmp eq i32 %a, 16 37; CHECK-NEXT: %alive.2 = icmp eq i32 %a, 8 38; CHECK-NEXT: %result = or i1 %alive.1, %alive.2 39 br i1 %flag, label %true, label %false 40 41true: 42 %cmp = icmp ult i32 %a, 16 43 call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 44 br label %continue 45 46false: 47 br label %continue 48 49continue: 50 %alive.1 = icmp eq i32 %a, 16 51 %alive.2 = icmp eq i32 %a, 8 52 %result = or i1 %alive.1, %alive.2 53 ret i1 %result 54} 55 56define i1 @test4(i32 %a, i1 %flag) { 57; CHECK-LABEL: @test4( 58; CHECK: continue: 59; CHECK-NEXT: %alive = icmp eq i32 %a, 12 60; CHECK-NEXT: %result = or i1 false, %alive 61 br i1 %flag, label %true, label %false 62 63true: 64 %cmp.t = icmp ult i32 %a, 16 65 call void(i1,...) @llvm.experimental.guard(i1 %cmp.t) [ "deopt"() ] 66 br label %continue 67 68false: 69 %cmp.f = icmp ult i32 %a, 12 70 call void(i1,...) @llvm.experimental.guard(i1 %cmp.f) [ "deopt"() ] 71 br label %continue 72 73continue: 74 %dead = icmp eq i32 %a, 16 75 %alive = icmp eq i32 %a, 12 76 %result = or i1 %dead, %alive 77 ret i1 %result 78} 79 80define i1 @test5(i32 %a) { 81; CHECK-LABEL: @test5( 82; CHECK: continue: 83; CHECK-NEXT: %alive = icmp eq i32 %a.plus.8, 16 84; CHECK-NEXT: %result = or i1 false, %alive 85 %cmp = icmp ult i32 %a, 16 86 call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 87 %a.plus.8 = add i32 %a, 8 88 br label %continue 89 90continue: 91 %dead = icmp eq i32 %a.plus.8, 24 92 %alive = icmp eq i32 %a.plus.8, 16 93 %result = or i1 %dead, %alive 94 ret i1 %result 95} 96 97; Check that we handle the case when the guard is the very first instruction in 98; a basic block. 99define i1 @test6(i32 %a) { 100; CHECK-LABEL: @test6( 101; CHECK: %alive = icmp eq i32 %a, 8 102; CHECK-NEXT: %result = or i1 false, %alive 103 %cmp = icmp ult i32 %a, 16 104 br label %continue 105 106continue: 107 call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 108 %dead = icmp eq i32 %a, 16 109 %alive = icmp eq i32 %a, 8 110 %result = or i1 %dead, %alive 111 ret i1 %result 112} 113