1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S < %s -instcombine | FileCheck %s 3; RUN: opt -S < %s -passes=instcombine | FileCheck %s 4 5define i1 @test_direct_implication(i1 %cond) { 6; CHECK-LABEL: @test_direct_implication( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 9; CHECK: if.true: 10; CHECK-NEXT: br label [[MERGE:%.*]] 11; CHECK: if.false: 12; CHECK-NEXT: br label [[MERGE]] 13; CHECK: merge: 14; CHECK-NEXT: ret i1 [[COND]] 15; 16entry: 17 br i1 %cond, label %if.true, label %if.false 18 19if.true: 20 br label %merge 21 22if.false: 23 br label %merge 24 25merge: 26 %ret = phi i1 [true, %if.true], [false, %if.false] 27 ret i1 %ret 28} 29 30define i1 @test_inverted_implication(i1 %cond) { 31; CHECK-LABEL: @test_inverted_implication( 32; CHECK-NEXT: entry: 33; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 34; CHECK: if.true: 35; CHECK-NEXT: br label [[MERGE:%.*]] 36; CHECK: if.false: 37; CHECK-NEXT: br label [[MERGE]] 38; CHECK: merge: 39; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND]], true 40; CHECK-NEXT: ret i1 [[TMP0]] 41; 42entry: 43 br i1 %cond, label %if.true, label %if.false 44 45if.true: 46 br label %merge 47 48if.false: 49 br label %merge 50 51merge: 52 %ret = phi i1 [false, %if.true], [true, %if.false] 53 ret i1 %ret 54} 55 56define i1 @test_direct_implication_complex_cfg(i1 %cond, i32 %cnt1) { 57; CHECK-LABEL: @test_direct_implication_complex_cfg( 58; CHECK-NEXT: entry: 59; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 60; CHECK: if.true: 61; CHECK-NEXT: br label [[LOOP1:%.*]] 62; CHECK: loop1: 63; CHECK-NEXT: [[IV1:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[IV1_NEXT:%.*]], [[LOOP1]] ] 64; CHECK-NEXT: [[IV1_NEXT]] = add i32 [[IV1]], 1 65; CHECK-NEXT: [[LOOP_COND_1:%.*]] = icmp slt i32 [[IV1_NEXT]], [[CNT1:%.*]] 66; CHECK-NEXT: br i1 [[LOOP_COND_1]], label [[LOOP1]], label [[IF_TRUE_END:%.*]] 67; CHECK: if.true.end: 68; CHECK-NEXT: br label [[MERGE:%.*]] 69; CHECK: if.false: 70; CHECK-NEXT: br label [[MERGE]] 71; CHECK: merge: 72; CHECK-NEXT: ret i1 [[COND]] 73; 74entry: 75 br i1 %cond, label %if.true, label %if.false 76 77if.true: 78 br label %loop1 79 80loop1: 81 %iv1 = phi i32 [0, %if.true], [%iv1.next, %loop1] 82 %iv1.next = add i32 %iv1, 1 83 %loop.cond.1 = icmp slt i32 %iv1.next, %cnt1 84 br i1 %loop.cond.1, label %loop1, label %if.true.end 85 86if.true.end: 87 br label %merge 88 89if.false: 90 br label %merge 91 92merge: 93 %ret = phi i1 [true, %if.true.end], [false, %if.false] 94 ret i1 %ret 95} 96 97define i1 @test_inverted_implication_complex_cfg(i1 %cond, i32 %cnt1) { 98; CHECK-LABEL: @test_inverted_implication_complex_cfg( 99; CHECK-NEXT: entry: 100; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 101; CHECK: if.true: 102; CHECK-NEXT: br label [[LOOP1:%.*]] 103; CHECK: loop1: 104; CHECK-NEXT: [[IV1:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[IV1_NEXT:%.*]], [[LOOP1]] ] 105; CHECK-NEXT: [[IV1_NEXT]] = add i32 [[IV1]], 1 106; CHECK-NEXT: [[LOOP_COND_1:%.*]] = icmp slt i32 [[IV1_NEXT]], [[CNT1:%.*]] 107; CHECK-NEXT: br i1 [[LOOP_COND_1]], label [[LOOP1]], label [[IF_TRUE_END:%.*]] 108; CHECK: if.true.end: 109; CHECK-NEXT: br label [[MERGE:%.*]] 110; CHECK: if.false: 111; CHECK-NEXT: br label [[MERGE]] 112; CHECK: merge: 113; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND]], true 114; CHECK-NEXT: ret i1 [[TMP0]] 115; 116entry: 117 br i1 %cond, label %if.true, label %if.false 118 119if.true: 120 br label %loop1 121 122loop1: 123 %iv1 = phi i32 [0, %if.true], [%iv1.next, %loop1] 124 %iv1.next = add i32 %iv1, 1 125 %loop.cond.1 = icmp slt i32 %iv1.next, %cnt1 126 br i1 %loop.cond.1, label %loop1, label %if.true.end 127 128if.true.end: 129 br label %merge 130 131if.false: 132 br label %merge 133 134merge: 135 %ret = phi i1 [false, %if.true.end], [true, %if.false] 136 ret i1 %ret 137} 138