1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5 6 7declare void @use(i1) 8 9define void @test_phi_not_in_loop_header() { 10; CHECK-LABEL: @test_phi_not_in_loop_header( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] 13; CHECK: outer.header: 14; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ] 15; CHECK-NEXT: br label [[INNER_HEADER:%.*]] 16; CHECK: inner.header: 17; CHECK-NEXT: [[CMP2_I:%.*]] = icmp eq i32 [[IV]], 3 18; CHECK-NEXT: br i1 [[CMP2_I]], label [[OUTER_LATCH]], label [[INNER_LATCH:%.*]] 19; CHECK: inner.latch: 20; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[IV]], 1 21; CHECK-NEXT: call void @use(i1 [[C]]) 22; CHECK-NEXT: br label [[INNER_HEADER]] 23; CHECK: outer.latch: 24; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 25; CHECK-NEXT: br label [[OUTER_HEADER]] 26; 27entry: 28 br label %outer.header 29 30outer.header: 31 %iv = phi i32 [ 1, %entry ], [ %iv.next, %outer.latch ] 32 br label %inner.header 33 34inner.header: 35 %cmp2.i = icmp eq i32 %iv, 3 36 br i1 %cmp2.i, label %outer.latch, label %inner.latch 37 38inner.latch: 39 %c = icmp uge i32 %iv, 1 40 call void @use(i1 %c) 41 br label %inner.header 42 43outer.latch: 44 %iv.next = add i32 %iv, 1 45 br label %outer.header 46} 47 48define void @multiple_successor_to_header_same_incoming(i8 %len.n, i16 %a, i1 %c.0) { 49; CHECK-LABEL: @multiple_successor_to_header_same_incoming( 50; CHECK-NEXT: entry: 51; CHECK-NEXT: [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16 52; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp uge i16 [[LEN]], [[A:%.*]] 53; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH_1:%.*]] 54; CHECK: loop.ph.1: 55; CHECK-NEXT: br i1 [[C_0:%.*]], label [[LOOP_PH_2:%.*]], label [[LOOP_PH_3:%.*]] 56; CHECK: loop.ph.2: 57; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 58; CHECK: loop.ph.3: 59; CHECK-NEXT: br label [[LOOP_HEADER]] 60; CHECK: loop.header: 61; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[LOOP_PH_2]] ], [ 0, [[LOOP_PH_3]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 62; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]] 63; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 64; CHECK: for.body: 65; CHECK-NEXT: [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]] 66; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 67; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 68; CHECK: loop.latch: 69; CHECK-NEXT: call void @use(i16 [[IV]]) 70; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1 71; CHECK-NEXT: br label [[LOOP_HEADER]] 72; CHECK: exit: 73; CHECK-NEXT: ret void 74; 75entry: 76 %len = zext i8 %len.n to i16 77 %len.neg = icmp uge i16 %len, %a 78 br i1 %len.neg, label %exit, label %loop.ph.1 79 80loop.ph.1: 81 br i1 %c.0, label %loop.ph.2, label %loop.ph.3 82 83loop.ph.2: 84 br label %loop.header 85 86loop.ph.3: 87 br label %loop.header 88 89loop.header: 90 %iv = phi i16 [ 0, %loop.ph.2 ], [ 0, %loop.ph.3 ], [ %iv.next, %loop.latch ] 91 %c = icmp eq i16 %iv, %len 92 br i1 %c, label %exit, label %for.body 93 94for.body: 95 %t.1 = icmp uge i16 %iv, 0 96 %t.2 = icmp ult i16 %iv, %a 97 %and = and i1 %t.1, %t.2 98 br i1 %and, label %loop.latch, label %exit 99 100loop.latch: 101 call void @use(i16 %iv) 102 %iv.next = add nuw nsw i16 %iv, 1 103 br label %loop.header 104 105exit: 106 ret void 107} 108 109define void @multiple_successor_to_header_different_incoming(i8 %len.n, i16 %a, i1 %c.0) { 110; CHECK-LABEL: @multiple_successor_to_header_different_incoming( 111; CHECK-NEXT: entry: 112; CHECK-NEXT: [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16 113; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp uge i16 [[LEN]], [[A:%.*]] 114; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH_1:%.*]] 115; CHECK: loop.ph.1: 116; CHECK-NEXT: br i1 [[C_0:%.*]], label [[LOOP_PH_2:%.*]], label [[LOOP_PH_3:%.*]] 117; CHECK: loop.ph.2: 118; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 119; CHECK: loop.ph.3: 120; CHECK-NEXT: br label [[LOOP_HEADER]] 121; CHECK: loop.header: 122; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[LOOP_PH_2]] ], [ 1, [[LOOP_PH_3]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 123; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]] 124; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 125; CHECK: for.body: 126; CHECK-NEXT: [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]] 127; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 128; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 129; CHECK: loop.latch: 130; CHECK-NEXT: call void @use(i16 [[IV]]) 131; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1 132; CHECK-NEXT: br label [[LOOP_HEADER]] 133; CHECK: exit: 134; CHECK-NEXT: ret void 135; 136entry: 137 %len = zext i8 %len.n to i16 138 %len.neg = icmp uge i16 %len, %a 139 br i1 %len.neg, label %exit, label %loop.ph.1 140 141loop.ph.1: 142 br i1 %c.0, label %loop.ph.2, label %loop.ph.3 143 144loop.ph.2: 145 br label %loop.header 146 147loop.ph.3: 148 br label %loop.header 149 150loop.header: 151 %iv = phi i16 [ 0, %loop.ph.2 ], [ 1, %loop.ph.3 ], [ %iv.next, %loop.latch ] 152 %c = icmp eq i16 %iv, %len 153 br i1 %c, label %exit, label %for.body 154 155for.body: 156 %t.1 = icmp uge i16 %iv, 0 157 %t.2 = icmp ult i16 %iv, %a 158 %and = and i1 %t.1, %t.2 159 br i1 %and, label %loop.latch, label %exit 160 161loop.latch: 162 call void @use(i16 %iv) 163 %iv.next = add nuw nsw i16 %iv, 1 164 br label %loop.header 165 166exit: 167 ret void 168} 169