1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -S -passes='structurizecfg' %s -o - | FileCheck %s 3 4define float @while_break(i32 %z, float %v, i32 %x, i32 %y) #0 { 5; CHECK-LABEL: define float @while_break( 6; CHECK-SAME: i32 [[Z:%.*]], float [[V:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0:[0-9]+]] { 7; CHECK-NEXT: [[ENTRY:.*]]: 8; CHECK-NEXT: br label %[[HEADER:.*]] 9; CHECK: [[HEADER]]: 10; CHECK-NEXT: [[V_1:%.*]] = phi float [ [[V]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[FLOW2:.*]] ] 11; CHECK-NEXT: [[IND:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[TMP5:%.*]], %[[FLOW2]] ] 12; CHECK-NEXT: [[CC:%.*]] = icmp sge i32 [[IND]], [[X]] 13; CHECK-NEXT: br i1 [[CC]], label %[[ELSE:.*]], label %[[FLOW:.*]] 14; CHECK: [[FLOW]]: 15; CHECK-NEXT: [[TMP0:%.*]] = phi float [ [[V_1]], %[[ELSE]] ], [ undef, %[[HEADER]] ] 16; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ [[CC2:%.*]], %[[ELSE]] ], [ false, %[[HEADER]] ] 17; CHECK-NEXT: [[TMP2:%.*]] = phi i1 [ false, %[[ELSE]] ], [ true, %[[HEADER]] ] 18; CHECK-NEXT: br i1 [[TMP2]], label %[[IF:.*]], label %[[FLOW1:.*]] 19; CHECK: [[IF]]: 20; CHECK-NEXT: [[V_IF:%.*]] = fadd float [[V_1]], 1.000000e+00 21; CHECK-NEXT: br label %[[FLOW1]] 22; CHECK: [[ELSE]]: 23; CHECK-NEXT: [[CC2]] = icmp slt i32 [[IND]], [[Y]] 24; CHECK-NEXT: br label %[[FLOW]] 25; CHECK: [[FLOW1]]: 26; CHECK-NEXT: [[TMP8]] = phi float [ [[V_IF]], %[[IF]] ], [ [[TMP0]], %[[FLOW]] ] 27; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ true, %[[IF]] ], [ [[TMP1]], %[[FLOW]] ] 28; CHECK-NEXT: br i1 [[TMP4]], label %[[LATCH:.*]], label %[[FLOW2]] 29; CHECK: [[LATCH]]: 30; CHECK-NEXT: [[IND_INC:%.*]] = add i32 [[IND]], 1 31; CHECK-NEXT: [[CC3:%.*]] = icmp slt i32 [[IND]], [[Z]] 32; CHECK-NEXT: br label %[[FLOW2]] 33; CHECK: [[FLOW2]]: 34; CHECK-NEXT: [[TMP5]] = phi i32 [ [[IND_INC]], %[[LATCH]] ], [ undef, %[[FLOW1]] ] 35; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ [[CC3]], %[[LATCH]] ], [ true, %[[FLOW1]] ] 36; CHECK-NEXT: br i1 [[TMP6]], label %[[END:.*]], label %[[HEADER]] 37; CHECK: [[END]]: 38; CHECK-NEXT: ret float [[TMP8]] 39; 40entry: 41 br label %header 42 43header: 44 %v.1 = phi float [ %v, %entry ], [ %v.2, %latch ] 45 %ind = phi i32 [ 0, %entry], [ %ind.inc, %latch ] 46 %cc = icmp slt i32 %ind, %x 47 br i1 %cc, label %if, label %else 48 49if: 50 %v.if = fadd float %v.1, 1.0 51 br label %latch 52 53else: 54 %cc2 = icmp slt i32 %ind, %y 55 br i1 %cc2, label %latch, label %end 56 57latch: 58 %v.2 = phi float [ %v.if, %if ], [ %v.1, %else ] 59 %ind.inc = add i32 %ind, 1 60 %cc3 = icmp slt i32 %ind, %z 61 br i1 %cc3, label %end, label %header 62 63end: 64 %r = phi float [ %v.2, %latch ], [ %v.1, %else ] 65 ret float %r 66} 67 68; Just different dfs order from while_break. 69define float @while_break2(i32 %z, float %v, i32 %x, i32 %y) #0 { 70; CHECK-LABEL: define float @while_break2( 71; CHECK-SAME: i32 [[Z:%.*]], float [[V:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] { 72; CHECK-NEXT: [[ENTRY:.*]]: 73; CHECK-NEXT: br label %[[HEADER:.*]] 74; CHECK: [[HEADER]]: 75; CHECK-NEXT: [[V_1:%.*]] = phi float [ [[V]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[FLOW2:.*]] ] 76; CHECK-NEXT: [[IND:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[TMP5:%.*]], %[[FLOW2]] ] 77; CHECK-NEXT: [[CC:%.*]] = icmp sge i32 [[IND]], [[X]] 78; CHECK-NEXT: br i1 [[CC]], label %[[IF:.*]], label %[[FLOW:.*]] 79; CHECK: [[IF]]: 80; CHECK-NEXT: [[V_IF:%.*]] = fadd float [[V_1]], 1.000000e+00 81; CHECK-NEXT: br label %[[FLOW]] 82; CHECK: [[FLOW]]: 83; CHECK-NEXT: [[TMP0:%.*]] = phi float [ [[V_IF]], %[[IF]] ], [ undef, %[[HEADER]] ] 84; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ true, %[[IF]] ], [ false, %[[HEADER]] ] 85; CHECK-NEXT: [[TMP2:%.*]] = phi i1 [ false, %[[IF]] ], [ true, %[[HEADER]] ] 86; CHECK-NEXT: br i1 [[TMP2]], label %[[ELSE:.*]], label %[[FLOW1:.*]] 87; CHECK: [[ELSE]]: 88; CHECK-NEXT: [[CC2:%.*]] = icmp slt i32 [[IND]], [[Y]] 89; CHECK-NEXT: br label %[[FLOW1]] 90; CHECK: [[FLOW1]]: 91; CHECK-NEXT: [[TMP8]] = phi float [ [[V_1]], %[[ELSE]] ], [ [[TMP0]], %[[FLOW]] ] 92; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[CC2]], %[[ELSE]] ], [ [[TMP1]], %[[FLOW]] ] 93; CHECK-NEXT: br i1 [[TMP4]], label %[[LATCH:.*]], label %[[FLOW2]] 94; CHECK: [[LATCH]]: 95; CHECK-NEXT: [[IND_INC:%.*]] = add i32 [[IND]], 1 96; CHECK-NEXT: [[CC3:%.*]] = icmp slt i32 [[IND]], [[Z]] 97; CHECK-NEXT: br label %[[FLOW2]] 98; CHECK: [[FLOW2]]: 99; CHECK-NEXT: [[TMP5]] = phi i32 [ [[IND_INC]], %[[LATCH]] ], [ undef, %[[FLOW1]] ] 100; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ [[CC3]], %[[LATCH]] ], [ true, %[[FLOW1]] ] 101; CHECK-NEXT: br i1 [[TMP6]], label %[[END:.*]], label %[[HEADER]] 102; CHECK: [[END]]: 103; CHECK-NEXT: ret float [[TMP8]] 104; 105entry: 106 br label %header 107 108header: 109 %v.1 = phi float [ %v, %entry ], [ %v.2, %latch ] 110 %ind = phi i32 [ 0, %entry], [ %ind.inc, %latch ] 111 %cc = icmp slt i32 %ind, %x 112 br i1 %cc, label %else, label %if 113 114if: 115 %v.if = fadd float %v.1, 1.0 116 br label %latch 117 118else: 119 %cc2 = icmp slt i32 %ind, %y 120 br i1 %cc2, label %latch, label %end 121 122latch: 123 %v.2 = phi float [ %v.if, %if ], [ %v.1, %else ] 124 %ind.inc = add i32 %ind, 1 125 %cc3 = icmp slt i32 %ind, %z 126 br i1 %cc3, label %end, label %header 127 128end: 129 %r = phi float [ %v.2, %latch ], [ %v.1, %else ] 130 ret float %r 131} 132 133; Two chains of phi network that have the same value from %if block. 134define < 2 x float> @while_break_two_chains_of_phi(float %v, i32 %x, i32 %y, i32 %z, ptr addrspace(1) %p) #0 { 135; CHECK-LABEL: define <2 x float> @while_break_two_chains_of_phi( 136; CHECK-SAME: float [[V:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], ptr addrspace(1) [[P:%.*]]) #[[ATTR0]] { 137; CHECK-NEXT: [[ENTRY:.*]]: 138; CHECK-NEXT: br label %[[HEADER:.*]] 139; CHECK: [[HEADER]]: 140; CHECK-NEXT: [[V_1:%.*]] = phi float [ [[V]], %[[ENTRY]] ], [ [[TMP8:%.*]], %[[FLOW1:.*]] ] 141; CHECK-NEXT: [[V_COPY:%.*]] = phi float [ 0.000000e+00, %[[ENTRY]] ], [ [[TMP7:%.*]], %[[FLOW1]] ] 142; CHECK-NEXT: [[IND:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[TMP3:%.*]], %[[FLOW1]] ] 143; CHECK-NEXT: [[CC:%.*]] = icmp slt i32 [[IND]], [[X]] 144; CHECK-NEXT: [[CC_INV:%.*]] = xor i1 [[CC]], true 145; CHECK-NEXT: br i1 [[CC]], label %[[IF:.*]], label %[[FLOW:.*]] 146; CHECK: [[IF]]: 147; CHECK-NEXT: [[V_PTR:%.*]] = getelementptr float, ptr addrspace(1) [[P]], i32 [[IND]] 148; CHECK-NEXT: [[V_LOAD:%.*]] = load float, ptr addrspace(1) [[V_PTR]], align 4 149; CHECK-NEXT: [[V_IF:%.*]] = fadd float [[V_LOAD]], 1.000000e+00 150; CHECK-NEXT: [[CC2:%.*]] = icmp slt i32 [[IND]], [[Y]] 151; CHECK-NEXT: br label %[[FLOW]] 152; CHECK: [[FLOW]]: 153; CHECK-NEXT: [[TMP7]] = phi float [ [[V_IF]], %[[IF]] ], [ [[V_COPY]], %[[HEADER]] ] 154; CHECK-NEXT: [[TMP8]] = phi float [ [[V_IF]], %[[IF]] ], [ [[V_1]], %[[HEADER]] ] 155; CHECK-NEXT: [[TMP2:%.*]] = phi i1 [ [[CC2]], %[[IF]] ], [ [[CC_INV]], %[[HEADER]] ] 156; CHECK-NEXT: br i1 [[TMP2]], label %[[LATCH:.*]], label %[[FLOW1]] 157; CHECK: [[LATCH]]: 158; CHECK-NEXT: [[IND_INC:%.*]] = add i32 [[IND]], 1 159; CHECK-NEXT: [[CC3:%.*]] = icmp slt i32 [[IND]], [[Z]] 160; CHECK-NEXT: br label %[[FLOW1]] 161; CHECK: [[FLOW1]]: 162; CHECK-NEXT: [[TMP3]] = phi i32 [ [[IND_INC]], %[[LATCH]] ], [ undef, %[[FLOW]] ] 163; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[CC3]], %[[LATCH]] ], [ true, %[[FLOW]] ] 164; CHECK-NEXT: br i1 [[TMP4]], label %[[END:.*]], label %[[HEADER]] 165; CHECK: [[END]]: 166; CHECK-NEXT: [[PACKED0:%.*]] = insertelement <2 x float> poison, float [[TMP8]], i32 0 167; CHECK-NEXT: [[PACKED1:%.*]] = insertelement <2 x float> [[PACKED0]], float [[TMP7]], i32 1 168; CHECK-NEXT: ret <2 x float> [[PACKED1]] 169; 170entry: 171 br label %header 172 173header: 174 %v.1 = phi float [ %v, %entry ], [ %v.2, %latch ] 175 %v.copy = phi float [ 0.0, %entry ], [ %v.copy.2, %latch ] 176 %ind = phi i32 [ 0, %entry], [ %ind.inc, %latch ] 177 %cc = icmp slt i32 %ind, %x 178 br i1 %cc, label %if, label %latch 179 180if: 181 %v.ptr = getelementptr float, ptr addrspace(1) %p, i32 %ind 182 %v.load = load float, ptr addrspace(1) %v.ptr 183 %v.if = fadd float %v.load, 1.0 184 %cc2 = icmp slt i32 %ind, %y 185 br i1 %cc2, label %latch, label %end 186 187latch: 188 %v.2 = phi float [ %v.1, %header ], [ %v.if, %if ] 189 %v.copy.2 = phi float [ %v.copy, %header ], [ %v.if, %if ] 190 %ind.inc = add i32 %ind, 1 191 %cc3 = icmp slt i32 %ind, %z 192 br i1 %cc3, label %end, label %header 193 194end: 195 %r = phi float [ %v.2, %latch ], [ %v.if, %if ] 196 %r2 = phi float [ %v.copy.2, %latch ], [ %v.if, %if ] 197 %packed0 = insertelement < 2 x float > poison, float %r, i32 0 198 %packed1 = insertelement < 2 x float > %packed0, float %r2, i32 1 199 ret < 2 x float> %packed1 200} 201 202attributes #0 = { nounwind } 203