1; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S %s | FileCheck --match-full-lines %s 2 3; The branch in %cont has !annotation metadata. Make sure generated AND 4; has !annotation metadata. 5define i32 @test_preserve_and(ptr %a, ptr %b, ptr %c, ptr %d) { 6; CHECK-LABEL: define {{.*}} @test_preserve_and({{.*}} 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[A:%.*]], [[B:%.*]], !annotation !0 9; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[C:%.*]], [[D:%.*]], !annotation !0 10; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false, !annotation !0 11; CHECK-NEXT: br i1 [[OR_COND]], label [[CONT1:%.*]], label [[TRAP:%.*]], !annotation !0 12; CHECK: trap: ; preds = %entry 13; CHECK-NEXT: call void @fn1() 14; CHECK-NEXT: unreachable 15; CHECK: cont1: ; preds = %entry 16; CHECK-NEXT: call void @fn2() 17; CHECK-NEXT: ret i32 0 18; 19entry: 20 %c.1 = icmp ult ptr %a, %b, !annotation !0 21 br i1 %c.1, label %cont, label %trap, !annotation !0 22 23cont: ; preds = %entry 24 %c.2 = icmp uge ptr %c, %d, !annotation !0 25 br i1 %c.2, label %cont1, label %trap, !annotation !0 26 27trap: ; preds = %cont, %entry 28 call void @fn1() 29 unreachable 30 31cont1: ; preds = %cont 32 call void @fn2() 33 ret i32 0 34} 35 36; The branch in %cont has !annotation metadata. Make sure generated OR 37; has !annotation metadata. 38define i32 @test_preserve_or(ptr %a, ptr %b, ptr %c, ptr %d) { 39; CHECK-LABEL: define {{.*}} @test_preserve_or({{.*}} 40; CHECK-NEXT: entry: 41; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[A:%.*]], [[B:%.*]], !annotation !0 42; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[C:%.*]], [[D:%.*]], !annotation !0 43; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_1]], i1 true, i1 [[C_2]], !annotation !0 44; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0 45; CHECK: trap: ; preds = %entry 46; CHECK-NEXT: call void @fn1() 47; CHECK-NEXT: unreachable 48; CHECK: cont1: ; preds = %entry 49; CHECK-NEXT: call void @fn2() 50; CHECK-NEXT: ret i32 0 51; 52entry: 53 %c.1 = icmp ult ptr %a, %b, !annotation !0 54 br i1 %c.1, label %cont, label %trap, !annotation !0 55 56cont: ; preds = %entry 57 %c.2 = icmp uge ptr %c, %d, !annotation !0 58 br i1 %c.2, label %trap, label %cont1, !annotation !0 59 60trap: ; preds = %cont, %entry 61 call void @fn1() 62 unreachable 63 64cont1: ; preds = %cont 65 call void @fn2() 66 ret i32 0 67} 68 69; The branch in %cont has !annotation metadata. Make sure generated negation 70; and OR have !annotation metadata. 71define i32 @test_preserve_or_not(ptr %a, ptr %b, ptr %c, ptr %d) { 72; CHECK-LABEL: define {{.*}} @test_preserve_or_not({{.*}} 73; CHECK-NEXT: entry: 74; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[A:%.*]], [[B:%.*]], !annotation !0 75; CHECK-NEXT: [[C_2:%.*]] = xor i1 [[C_1]], true 76; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true, !annotation !0 77; CHECK-NEXT: [[C_3:%.*]] = icmp uge ptr [[C:%.*]], [[D:%.*]], !annotation !0 78; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_2_NOT]], i1 true, i1 [[C_3]], !annotation !0 79; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0 80; CHECK: trap: ; preds = %entry 81; CHECK-NEXT: call void @fn1() 82; CHECK-NEXT: unreachable 83; CHECK: cont1: ; preds = %entry 84; CHECK-NEXT: call void @fn2() 85; CHECK-NEXT: ret i32 0 86; 87entry: 88 %c.1 = icmp ult ptr %a, %b, !annotation !0 89 %c.2 = xor i1 %c.1, true 90 br i1 %c.2, label %cont, label %trap, !annotation !0 91 92cont: ; preds = %entry 93 %c.3 = icmp uge ptr %c, %d, !annotation !0 94 br i1 %c.3, label %trap, label %cont1, !annotation !0 95 96trap: ; preds = %cont, %entry 97 call void @fn1() 98 unreachable 99 100cont1: ; preds = %cont 101 call void @fn2() 102 ret i32 0 103} 104 105 106; The branch in %cont has no !annotation metadata. Make sure generated negation 107; and OR do not have !annotation metadata. 108define i32 @test_or_not_no_annotation(ptr %a, ptr %b, ptr %c, ptr %d) { 109; CHECK-LABEL: define {{.*}} @test_or_not_no_annotation({{.*}} 110; CHECK-NEXT: entry: 111; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[A:%.*]], [[B:%.*]], !annotation !0 112; CHECK-NEXT: [[C_2:%.*]] = xor i1 [[C_1]], true 113; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true 114; CHECK-NEXT: [[C_3:%.*]] = icmp uge ptr [[C:%.*]], [[D:%.*]], !annotation !0 115; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_2_NOT]], i1 true, i1 [[C_3]] 116; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0 117; CHECK: trap: ; preds = %entry 118; CHECK-NEXT: call void @fn1() 119; CHECK-NEXT: unreachable 120; CHECK: cont1: ; preds = %entry 121; CHECK-NEXT: call void @fn2() 122; CHECK-NEXT: ret i32 0 123; 124entry: 125 %c.1 = icmp ult ptr %a, %b, !annotation !0 126 %c.2 = xor i1 %c.1, true 127 br i1 %c.2, label %cont, label %trap, !annotation !0 128 129cont: ; preds = %entry 130 %c.3 = icmp uge ptr %c, %d, !annotation !0 131 br i1 %c.3, label %trap, label %cont1 132 133trap: ; preds = %cont, %entry 134 call void @fn1() 135 unreachable 136 137cont1: ; preds = %cont 138 call void @fn2() 139 ret i32 0 140} 141 142declare void @fn1() 143declare void @fn2() 144 145!0 = !{!"foo"} 146