1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -mtriple=amdgcn-- -S -o - -structurizecfg -structurizecfg-skip-uniform-regions -structurizecfg-relaxed-uniform-regions -enable-new-pm=0 < %s | FileCheck %s 3 4define amdgpu_cs void @uniform(i32 inreg %v) { 5; CHECK-LABEL: @uniform( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CC:%.*]] = icmp eq i32 [[V:%.*]], 0 8; CHECK-NEXT: br i1 [[CC]], label [[IF:%.*]], label [[END:%.*]], !structurizecfg.uniform !0 9; CHECK: if: 10; CHECK-NEXT: br label [[END]], !structurizecfg.uniform !0 11; CHECK: end: 12; CHECK-NEXT: ret void 13; 14entry: 15 %cc = icmp eq i32 %v, 0 16 br i1 %cc, label %if, label %end 17 18if: 19 br label %end 20 21end: 22 ret void 23} 24 25define amdgpu_cs void @nonuniform(i32 addrspace(4)* %ptr) { 26; CHECK-LABEL: @nonuniform( 27; CHECK-NEXT: entry: 28; CHECK-NEXT: br label [[FOR_BODY:%.*]] 29; CHECK: for.body: 30; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[FLOW:%.*]] ] 31; CHECK-NEXT: [[CC:%.*]] = icmp ult i32 [[I]], 4 32; CHECK-NEXT: br i1 [[CC]], label [[MID_LOOP:%.*]], label [[FLOW]] 33; CHECK: mid.loop: 34; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.workitem.id.x() 35; CHECK-NEXT: [[CC2:%.*]] = icmp eq i32 [[V]], 0 36; CHECK-NEXT: br i1 [[CC2]], label [[END_LOOP:%.*]], label [[FLOW1:%.*]] 37; CHECK: Flow: 38; CHECK-NEXT: [[TMP0]] = phi i32 [ [[TMP2:%.*]], [[FLOW1]] ], [ undef, [[FOR_BODY]] ] 39; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ [[TMP3:%.*]], [[FLOW1]] ], [ true, [[FOR_BODY]] ] 40; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_END:%.*]], label [[FOR_BODY]] 41; CHECK: end.loop: 42; CHECK-NEXT: [[I_INC:%.*]] = add i32 [[I]], 1 43; CHECK-NEXT: br label [[FLOW1]] 44; CHECK: Flow1: 45; CHECK-NEXT: [[TMP2]] = phi i32 [ [[I_INC]], [[END_LOOP]] ], [ undef, [[MID_LOOP]] ] 46; CHECK-NEXT: [[TMP3]] = phi i1 [ false, [[END_LOOP]] ], [ true, [[MID_LOOP]] ] 47; CHECK-NEXT: br label [[FLOW]] 48; CHECK: for.end: 49; CHECK-NEXT: br i1 [[CC]], label [[IF:%.*]], label [[END:%.*]] 50; CHECK: if: 51; CHECK-NEXT: br label [[END]] 52; CHECK: end: 53; CHECK-NEXT: ret void 54; 55entry: 56 br label %for.body 57 58for.body: 59 %i = phi i32 [0, %entry], [%i.inc, %end.loop] 60 %cc = icmp ult i32 %i, 4 61 br i1 %cc, label %mid.loop, label %for.end 62 63mid.loop: 64 %v = call i32 @llvm.amdgcn.workitem.id.x() 65 %cc2 = icmp eq i32 %v, 0 66 br i1 %cc2, label %end.loop, label %for.end 67 68end.loop: 69 %i.inc = add i32 %i, 1 70 br label %for.body 71 72for.end: 73 br i1 %cc, label %if, label %end 74 75if: 76 br label %end 77 78end: 79 ret void 80} 81 82define amdgpu_cs void @uniform_branch_to_nonuniform_subregions(i32 addrspace(4)* %ptr, i32 inreg %data) { 83; CHECK-LABEL: @uniform_branch_to_nonuniform_subregions( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[DATA:%.*]], 42 86; CHECK-NEXT: br i1 [[C]], label [[UNIFORM_FOR_BODY:%.*]], label [[FOR_BODY:%.*]], !structurizecfg.uniform !0 87; CHECK: for.body: 88; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[FLOW1:%.*]] ] 89; CHECK-NEXT: [[CC:%.*]] = icmp ult i32 [[I]], 4 90; CHECK-NEXT: br i1 [[CC]], label [[MID_LOOP:%.*]], label [[FLOW1]] 91; CHECK: mid.loop: 92; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.workitem.id.x() 93; CHECK-NEXT: [[CC2:%.*]] = icmp eq i32 [[V]], 0 94; CHECK-NEXT: br i1 [[CC2]], label [[END_LOOP:%.*]], label [[FLOW2:%.*]] 95; CHECK: Flow1: 96; CHECK-NEXT: [[TMP0]] = phi i32 [ [[TMP2:%.*]], [[FLOW2]] ], [ undef, [[FOR_BODY]] ] 97; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ [[TMP3:%.*]], [[FLOW2]] ], [ true, [[FOR_BODY]] ] 98; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_END:%.*]], label [[FOR_BODY]] 99; CHECK: end.loop: 100; CHECK-NEXT: [[I_INC:%.*]] = add i32 [[I]], 1 101; CHECK-NEXT: br label [[FLOW2]] 102; CHECK: Flow2: 103; CHECK-NEXT: [[TMP2]] = phi i32 [ [[I_INC]], [[END_LOOP]] ], [ undef, [[MID_LOOP]] ] 104; CHECK-NEXT: [[TMP3]] = phi i1 [ false, [[END_LOOP]] ], [ true, [[MID_LOOP]] ] 105; CHECK-NEXT: br label [[FLOW1]] 106; CHECK: for.end: 107; CHECK-NEXT: br i1 [[CC]], label [[IF:%.*]], label [[FLOW:%.*]] 108; CHECK: if: 109; CHECK-NEXT: br label [[FLOW]] 110; CHECK: uniform.for.body: 111; CHECK-NEXT: [[UNIFORM_I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP4:%.*]], [[FLOW4:%.*]] ] 112; CHECK-NEXT: [[UNIFORM_CC:%.*]] = icmp ult i32 [[UNIFORM_I]], 4 113; CHECK-NEXT: br i1 [[UNIFORM_CC]], label [[UNIFORM_MID_LOOP:%.*]], label [[FLOW4]] 114; CHECK: uniform.mid.loop: 115; CHECK-NEXT: [[UNIFORM_V:%.*]] = call i32 @llvm.amdgcn.workitem.id.x() 116; CHECK-NEXT: [[UNIFORM_CC2:%.*]] = icmp eq i32 [[UNIFORM_V]], 0 117; CHECK-NEXT: br i1 [[UNIFORM_CC2]], label [[UNIFORM_END_LOOP:%.*]], label [[FLOW5:%.*]] 118; CHECK: Flow4: 119; CHECK-NEXT: [[TMP4]] = phi i32 [ [[TMP6:%.*]], [[FLOW5]] ], [ undef, [[UNIFORM_FOR_BODY]] ] 120; CHECK-NEXT: [[TMP5:%.*]] = phi i1 [ [[TMP7:%.*]], [[FLOW5]] ], [ true, [[UNIFORM_FOR_BODY]] ] 121; CHECK-NEXT: br i1 [[TMP5]], label [[UNIFORM_FOR_END:%.*]], label [[UNIFORM_FOR_BODY]] 122; CHECK: uniform.end.loop: 123; CHECK-NEXT: [[UNIFORM_I_INC:%.*]] = add i32 [[UNIFORM_I]], 1 124; CHECK-NEXT: br label [[FLOW5]] 125; CHECK: Flow5: 126; CHECK-NEXT: [[TMP6]] = phi i32 [ [[UNIFORM_I_INC]], [[UNIFORM_END_LOOP]] ], [ undef, [[UNIFORM_MID_LOOP]] ] 127; CHECK-NEXT: [[TMP7]] = phi i1 [ false, [[UNIFORM_END_LOOP]] ], [ true, [[UNIFORM_MID_LOOP]] ] 128; CHECK-NEXT: br label [[FLOW4]] 129; CHECK: uniform.for.end: 130; CHECK-NEXT: br i1 [[UNIFORM_CC]], label [[UNIFORM_IF:%.*]], label [[FLOW3:%.*]] 131; CHECK: uniform.if: 132; CHECK-NEXT: br label [[FLOW3]] 133; CHECK: Flow: 134; CHECK-NEXT: br label [[END:%.*]] 135; CHECK: Flow3: 136; CHECK-NEXT: br label [[END]] 137; CHECK: end: 138; CHECK-NEXT: ret void 139; 140entry: 141 %c = icmp eq i32 %data, 42 142 br i1 %c, label %uniform.for.body, label %for.body 143 144for.body: 145 %i = phi i32 [0, %entry], [%i.inc, %end.loop] 146 %cc = icmp ult i32 %i, 4 147 br i1 %cc, label %mid.loop, label %for.end 148 149mid.loop: 150 %v = call i32 @llvm.amdgcn.workitem.id.x() 151 %cc2 = icmp eq i32 %v, 0 152 br i1 %cc2, label %end.loop, label %for.end 153 154end.loop: 155 %i.inc = add i32 %i, 1 156 br label %for.body 157 158for.end: 159 br i1 %cc, label %if, label %end 160 161if: 162 br label %end 163 164uniform.for.body: 165 %uniform.i = phi i32 [0, %entry], [%uniform.i.inc, %uniform.end.loop] 166 %uniform.cc = icmp ult i32 %uniform.i, 4 167 br i1 %uniform.cc, label %uniform.mid.loop, label %uniform.for.end 168 169uniform.mid.loop: 170 %uniform.v = call i32 @llvm.amdgcn.workitem.id.x() 171 %uniform.cc2 = icmp eq i32 %uniform.v, 0 172 br i1 %uniform.cc2, label %uniform.end.loop, label %uniform.for.end 173 174uniform.end.loop: 175 %uniform.i.inc = add i32 %uniform.i, 1 176 br label %uniform.for.body 177 178uniform.for.end: 179 br i1 %uniform.cc, label %uniform.if, label %end 180 181uniform.if: 182 br label %end 183 184end: 185 ret void 186} 187 188declare i32 @llvm.amdgcn.workitem.id.x() 189