496 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -mcpu=gfx900 -amdgpu-lower-buffer-fat-pointers < %s | FileCheck %s3; RUN: opt -S -mcpu=gfx900 -passes=amdgpu-lower-buffer-fat-pointers < %s | FileCheck %s4 5target triple = "amdgcn--"6 7;; This should optimize to just the offset part8define float @sum(ptr addrspace(8) %buf, i32 %len) {9; CHECK-LABEL: define float @sum10; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {11; CHECK-NEXT: entry:12; CHECK-NEXT: br label [[LOOP:%.*]]13; CHECK: loop:14; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]15; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]16; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]17; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)18; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]19; CHECK-NEXT: [[PTR]] = add i32 [[PTR_PREV_OFF]], 420; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 121; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]22; CHECK-NEXT: br i1 [[TEST]], label [[LOOP]], label [[EXIT:%.*]]23; CHECK: exit:24; CHECK-NEXT: ret float [[SUM]]25;26entry:27 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)28 br label %loop29loop:30 %sum.prev = phi float [ %sum, %loop ], [ 0.0, %entry ]31 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop ], [ %start, %entry ]32 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]33 34 %val = load float, ptr addrspace(7) %ptr.prev35 %sum = fadd float %sum.prev, %val36 37 %ptr = getelementptr float, ptr addrspace(7) %ptr.prev, i32 138 %i.next = add i32 %i, 139 %test = icmp ult i32 %i.next, %len40 br i1 %test, label %loop, label %exit41exit:42 ret float %sum43}44 45;; But this should not46define float @sum_integer_ops(ptr addrspace(8) %buf, i32 %len) {47; CHECK-LABEL: define float @sum_integer_ops48; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {49; CHECK-NEXT: entry:50; CHECK-NEXT: br label [[LOOP:%.*]]51; CHECK: loop:52; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]53; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]54; CHECK-NEXT: [[PTR_PREV_RSRC:%.*]] = phi ptr addrspace(8) [ [[PTR_RSRC:%.*]], [[LOOP]] ], [ [[BUF]], [[ENTRY]] ]55; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR_OFF:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]56; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[PTR_PREV_RSRC]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)57; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]58; CHECK-NEXT: [[PTR_PREV_INT_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[PTR_PREV_RSRC]] to i16059; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i160 [[PTR_PREV_INT_RSRC]], 3260; CHECK-NEXT: [[PTR_PREV_INT_OFF:%.*]] = zext i32 [[PTR_PREV_OFF]] to i16061; CHECK-NEXT: [[PTR_PREV_INT:%.*]] = or i160 [[TMP0]], [[PTR_PREV_INT_OFF]]62; CHECK-NEXT: [[PTR_INT:%.*]] = add i160 [[PTR_PREV_INT]], 463; CHECK-NEXT: [[TMP1:%.*]] = lshr i160 [[PTR_INT]], 3264; CHECK-NEXT: [[TMP2:%.*]] = trunc i160 [[TMP1]] to i12865; CHECK-NEXT: [[PTR_RSRC]] = inttoptr i128 [[TMP2]] to ptr addrspace(8)66; CHECK-NEXT: [[PTR_OFF]] = trunc i160 [[PTR_INT]] to i3267; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 168; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]69; CHECK-NEXT: br i1 [[TEST]], label [[LOOP]], label [[EXIT:%.*]]70; CHECK: exit:71; CHECK-NEXT: ret float [[SUM]]72;73entry:74 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)75 br label %loop76loop:77 %sum.prev = phi float [ %sum, %loop ], [ 0.0, %entry ]78 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop ], [ %start, %entry ]79 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]80 81 %val = load float, ptr addrspace(7) %ptr.prev82 %sum = fadd float %sum.prev, %val83 84 %ptr.prev.int = ptrtoint ptr addrspace(7) %ptr.prev to i16085 %ptr.int = add i160 %ptr.prev.int, 486 %ptr = inttoptr i160 %ptr.int to ptr addrspace(7)87 %i.next = add i32 %i, 188 %test = icmp ult i32 %i.next, %len89 br i1 %test, label %loop, label %exit90exit:91 ret float %sum92}93 94;; Should go to offsets only95define float @sum_2d(ptr addrspace(8) %buf, i32 %ii, i32 %jj) {96; CHECK-LABEL: define float @sum_2d97; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[II:%.*]], i32 [[JJ:%.*]]) #[[ATTR0]] {98; CHECK-NEXT: entry:99; CHECK-NEXT: br label [[LOOP1_ENTRY:%.*]]100; CHECK: loop1.entry:101; CHECK-NEXT: [[SUM1_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP1_EXIT:%.*]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]102; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP1_EXIT]] ], [ 0, [[ENTRY]] ]103; CHECK-NEXT: [[PTR1_PREV_OFF:%.*]] = phi i32 [ [[PTR1:%.*]], [[LOOP1_EXIT]] ], [ 0, [[ENTRY]] ]104; CHECK-NEXT: br label [[LOOP2:%.*]]105; CHECK: loop2:106; CHECK-NEXT: [[SUM2_PREV:%.*]] = phi float [ [[SUM]], [[LOOP2]] ], [ [[SUM1_PREV]], [[LOOP1_ENTRY]] ]107; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP2]] ], [ 0, [[LOOP1_ENTRY]] ]108; CHECK-NEXT: [[PTR2_PREV_OFF:%.*]] = phi i32 [ [[PTR2:%.*]], [[LOOP2]] ], [ [[PTR1_PREV_OFF]], [[LOOP1_ENTRY]] ]109; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 [[PTR2_PREV_OFF]], i32 0, i32 0)110; CHECK-NEXT: [[SUM]] = fadd float [[SUM2_PREV]], [[VAL]]111; CHECK-NEXT: [[PTR2]] = add i32 [[PTR2_PREV_OFF]], 4112; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1113; CHECK-NEXT: [[TEST2:%.*]] = icmp ult i32 [[J_NEXT]], [[JJ]]114; CHECK-NEXT: br i1 [[TEST2]], label [[LOOP2]], label [[LOOP1_EXIT]]115; CHECK: loop1.exit:116; CHECK-NEXT: [[PTR1]] = add i32 [[PTR2]], 4117; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1118; CHECK-NEXT: [[TEST1:%.*]] = icmp ult i32 [[I_NEXT]], [[II]]119; CHECK-NEXT: br i1 [[TEST1]], label [[LOOP1_ENTRY]], label [[EXIT:%.*]]120; CHECK: exit:121; CHECK-NEXT: ret float [[SUM]]122;123entry:124 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)125 br label %loop1.entry126loop1.entry:127 %sum1.prev = phi float [ %sum, %loop1.exit ], [ 0.0, %entry ]128 %ptr1.prev = phi ptr addrspace(7) [ %ptr1, %loop1.exit ], [ %start, %entry ]129 %i = phi i32 [ %i.next, %loop1.exit ], [ 0, %entry ]130 131 br label %loop2132loop2:133 %sum2.prev = phi float [ %sum, %loop2 ], [ %sum1.prev, %loop1.entry ]134 %ptr2.prev = phi ptr addrspace(7) [ %ptr2, %loop2 ], [ %ptr1.prev, %loop1.entry ]135 %j = phi i32 [ %j.next, %loop2 ], [ 0, %loop1.entry ]136 137 %val = load float, ptr addrspace(7) %ptr2.prev138 %sum = fadd float %sum2.prev, %val139 140 %ptr2 = getelementptr float, ptr addrspace(7) %ptr2.prev, i32 1141 %j.next = add i32 %j, 1142 %test2 = icmp ult i32 %j.next, %jj143 144 br i1 %test2, label %loop2, label %loop1.exit145loop1.exit:146 %ptr1 = getelementptr float, ptr addrspace(7) %ptr2, i32 1147 %i.next = add i32 %i, 1148 %test1 = icmp ult i32 %i.next, %ii149 br i1 %test1, label %loop1.entry, label %exit150exit:151 ret float %sum152}153 154;; This should optimize to just the offset parts since all the arguments to the155;; select point to the same buffer.156define float @sum_jump_on_negative(ptr addrspace(8) %buf, i32 %len) {157; CHECK-LABEL: define float @sum_jump_on_negative158; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {159; CHECK-NEXT: entry:160; CHECK-NEXT: br label [[LOOP:%.*]]161; CHECK: loop:162; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]163; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]164; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR_OFF:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]165; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)166; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]167; CHECK-NEXT: [[SKIP_NEXT:%.*]] = fcmp olt float [[VAL]], 0.000000e+00168; CHECK-NEXT: [[SMALL_JUMP:%.*]] = add i32 [[PTR_PREV_OFF]], 4169; CHECK-NEXT: [[LARGE_JUMP:%.*]] = add i32 [[PTR_PREV_OFF]], 8170; CHECK-NEXT: [[PTR_OFF]] = select i1 [[SKIP_NEXT]], i32 [[LARGE_JUMP]], i32 [[SMALL_JUMP]]171; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1172; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]173; CHECK-NEXT: br i1 [[TEST]], label [[LOOP]], label [[EXIT:%.*]]174; CHECK: exit:175; CHECK-NEXT: ret float [[SUM]]176;177entry:178 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)179 br label %loop180loop:181 %sum.prev = phi float [ %sum, %loop ], [ 0.0, %entry ]182 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop ], [ %start, %entry ]183 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]184 185 %val = load float, ptr addrspace(7) %ptr.prev186 %sum = fadd float %sum.prev, %val187 188 %skip.next = fcmp olt float %val, 0.0189 %small.jump = getelementptr float, ptr addrspace(7) %ptr.prev, i32 1190 %large.jump = getelementptr float, ptr addrspace(7) %ptr.prev, i32 2191 %ptr = select i1 %skip.next, ptr addrspace(7) %large.jump, ptr addrspace(7) %small.jump192 193 %i.next = add i32 %i, 1194 %test = icmp ult i32 %i.next, %len195 br i1 %test, label %loop, label %exit196exit:197 ret float %sum198}199 200define float @sum_jump_on_negative_with_phi(ptr addrspace(8) %buf, i32 %len) {201; CHECK-LABEL: define float @sum_jump_on_negative_with_phi202; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {203; CHECK-NEXT: entry:204; CHECK-NEXT: br label [[LOOP:%.*]]205; CHECK: loop:206; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP_EXIT:%.*]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]207; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP_EXIT]] ], [ 0, [[ENTRY]] ]208; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR_OFF:%.*]], [[LOOP_EXIT]] ], [ 0, [[ENTRY]] ]209; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)210; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]211; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1212; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]213; CHECK-NEXT: [[SKIP_NEXT:%.*]] = fcmp olt float [[VAL]], 0.000000e+00214; CHECK-NEXT: br i1 [[SKIP_NEXT]], label [[THEN:%.*]], label [[ELSE:%.*]]215; CHECK: then:216; CHECK-NEXT: [[LARGE_JUMP:%.*]] = add i32 [[PTR_PREV_OFF]], 8217; CHECK-NEXT: br label [[LOOP_EXIT]]218; CHECK: else:219; CHECK-NEXT: [[SMALL_JUMP:%.*]] = add i32 [[PTR_PREV_OFF]], 4220; CHECK-NEXT: br label [[LOOP_EXIT]]221; CHECK: loop.exit:222; CHECK-NEXT: [[PTR_OFF]] = phi i32 [ [[LARGE_JUMP]], [[THEN]] ], [ [[SMALL_JUMP]], [[ELSE]] ]223; CHECK-NEXT: br i1 [[TEST]], label [[LOOP]], label [[EXIT:%.*]]224; CHECK: exit:225; CHECK-NEXT: ret float [[SUM]]226;227entry:228 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)229 br label %loop230loop:231 %sum.prev = phi float [ %sum, %loop.exit ], [ 0.0, %entry ]232 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop.exit ], [ %start, %entry ]233 %i = phi i32 [ %i.next, %loop.exit ], [ 0, %entry ]234 235 %val = load float, ptr addrspace(7) %ptr.prev236 %sum = fadd float %sum.prev, %val237 238 %i.next = add i32 %i, 1239 %test = icmp ult i32 %i.next, %len240 241 %skip.next = fcmp olt float %val, 0.0242 br i1 %skip.next, label %then, label %else243then:244 %large.jump = getelementptr float, ptr addrspace(7) %ptr.prev, i32 2245 br label %loop.exit246else:247 %small.jump = getelementptr float, ptr addrspace(7) %ptr.prev, i32 1248 br label %loop.exit249loop.exit:250 %ptr = phi ptr addrspace(7) [ %large.jump, %then ], [ %small.jump, %else ]251 br i1 %test, label %loop, label %exit252exit:253 ret float %sum254}255 256;; But this has a shifting resource part.257define float @sum_new_buffer_on_negative(ptr addrspace(8) %buf1, ptr addrspace(8) %buf2, i32 %len) {258; CHECK-LABEL: define float @sum_new_buffer_on_negative259; CHECK-SAME: (ptr addrspace(8) [[BUF1:%.*]], ptr addrspace(8) [[BUF2:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {260; CHECK-NEXT: entry:261; CHECK-NEXT: br label [[LOOP:%.*]]262; CHECK: loop:263; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]264; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]265; CHECK-NEXT: [[PTR_PREV_RSRC:%.*]] = phi ptr addrspace(8) [ [[PTR_RSRC:%.*]], [[LOOP]] ], [ [[BUF1]], [[ENTRY]] ]266; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR_OFF:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]267; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[PTR_PREV_RSRC]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)268; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]269; CHECK-NEXT: [[HOP:%.*]] = fcmp olt float [[VAL]], 0.000000e+00270; CHECK-NEXT: [[THIS_NEXT:%.*]] = add i32 [[PTR_PREV_OFF]], 4271; CHECK-NEXT: [[PTR_RSRC]] = select i1 [[HOP]], ptr addrspace(8) [[PTR_PREV_RSRC]], ptr addrspace(8) [[BUF2]]272; CHECK-NEXT: [[PTR_OFF]] = select i1 [[HOP]], i32 [[THIS_NEXT]], i32 0273; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1274; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]275; CHECK-NEXT: br i1 [[TEST]], label [[LOOP]], label [[EXIT:%.*]]276; CHECK: exit:277; CHECK-NEXT: ret float [[SUM]]278;279entry:280 %start = addrspacecast ptr addrspace(8) %buf1 to ptr addrspace(7)281 %start2 = addrspacecast ptr addrspace(8) %buf2 to ptr addrspace(7)282 br label %loop283loop:284 %sum.prev = phi float [ %sum, %loop ], [ 0.0, %entry ]285 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop ], [ %start, %entry ]286 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]287 288 %val = load float, ptr addrspace(7) %ptr.prev289 %sum = fadd float %sum.prev, %val290 291 %hop = fcmp olt float %val, 0.0292 %this.next = getelementptr float, ptr addrspace(7) %ptr.prev, i32 1293 %ptr = select i1 %hop, ptr addrspace(7) %this.next, ptr addrspace(7) %start2294 295 %i.next = add i32 %i, 1296 %test = icmp ult i32 %i.next, %len297 br i1 %test, label %loop, label %exit298exit:299 ret float %sum300}301 302;; As does this.303define float @sum_new_buffer_on_negative_with_phi(ptr addrspace(8) %buf1, ptr addrspace(8) %buf2, i32 %len) {304; CHECK-LABEL: define float @sum_new_buffer_on_negative_with_phi305; CHECK-SAME: (ptr addrspace(8) [[BUF1:%.*]], ptr addrspace(8) [[BUF2:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {306; CHECK-NEXT: entry:307; CHECK-NEXT: br label [[LOOP:%.*]]308; CHECK: loop:309; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP_EXIT:%.*]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]310; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP_EXIT]] ], [ 0, [[ENTRY]] ]311; CHECK-NEXT: [[PTR_PREV_RSRC:%.*]] = phi ptr addrspace(8) [ [[PTR_RSRC:%.*]], [[LOOP_EXIT]] ], [ [[BUF1]], [[ENTRY]] ]312; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR_OFF:%.*]], [[LOOP_EXIT]] ], [ 0, [[ENTRY]] ]313; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[PTR_PREV_RSRC]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)314; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]315; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1316; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]317; CHECK-NEXT: [[HOP:%.*]] = fcmp olt float [[VAL]], 0.000000e+00318; CHECK-NEXT: br i1 [[HOP]], label [[THEN:%.*]], label [[LOOP_EXIT]]319; CHECK: then:320; CHECK-NEXT: [[THIS_NEXT:%.*]] = add i32 [[PTR_PREV_OFF]], 4321; CHECK-NEXT: br label [[LOOP_EXIT]]322; CHECK: loop.exit:323; CHECK-NEXT: [[PTR_RSRC]] = phi ptr addrspace(8) [ [[PTR_PREV_RSRC]], [[THEN]] ], [ [[BUF2]], [[LOOP]] ]324; CHECK-NEXT: [[PTR_OFF]] = phi i32 [ [[THIS_NEXT]], [[THEN]] ], [ 0, [[LOOP]] ]325; CHECK-NEXT: br i1 [[TEST]], label [[LOOP]], label [[EXIT:%.*]]326; CHECK: exit:327; CHECK-NEXT: ret float [[SUM]]328;329entry:330 %start = addrspacecast ptr addrspace(8) %buf1 to ptr addrspace(7)331 %start2 = addrspacecast ptr addrspace(8) %buf2 to ptr addrspace(7)332 br label %loop333loop:334 %sum.prev = phi float [ %sum, %loop.exit ], [ 0.0, %entry ]335 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop.exit ], [ %start, %entry ]336 %i = phi i32 [ %i.next, %loop.exit ], [ 0, %entry ]337 338 %val = load float, ptr addrspace(7) %ptr.prev339 %sum = fadd float %sum.prev, %val340 341 %i.next = add i32 %i, 1342 %test = icmp ult i32 %i.next, %len343 %hop = fcmp olt float %val, 0.0344 br i1 %hop, label %then, label %loop.exit345then:346 %this.next = getelementptr float, ptr addrspace(7) %ptr.prev, i32 1347 br label %loop.exit348loop.exit:349 %ptr = phi ptr addrspace(7) [ %this.next, %then ], [ %start2, %loop ]350 br i1 %test, label %loop, label %exit351exit:352 ret float %sum353}354 355;; Test that the uniform buffer descriptor optimization works correctly for phi356;; nodes that repeat the same predecessor multiple times.357define float @sum_duplicate_preds(ptr addrspace(8) %buf, i32 %len) {358; CHECK-LABEL: define float @sum_duplicate_preds359; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {360; CHECK-NEXT: entry:361; CHECK-NEXT: br label [[LOOP:%.*]]362; CHECK: loop:363; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP]] ], [ [[SUM]], [[LOOP]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]364; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ], [ [[I_NEXT]], [[LOOP]] ]365; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ], [ [[PTR]], [[LOOP]] ]366; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)367; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]368; CHECK-NEXT: [[PTR]] = add i32 [[PTR_PREV_OFF]], 4369; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1370; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]371; CHECK-NEXT: [[TEST_EXT:%.*]] = zext i1 [[TEST]] to i32372; CHECK-NEXT: switch i32 [[TEST_EXT]], label [[LOOP]] [373; CHECK-NEXT: i32 1, label [[LOOP]]374; CHECK-NEXT: i32 0, label [[EXIT:%.*]]375; CHECK-NEXT: ]376; CHECK: exit:377; CHECK-NEXT: ret float [[SUM]]378;379entry:380 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)381 br label %loop382loop:383 %sum.prev = phi float [ %sum, %loop ], [ %sum, %loop ], [ 0.0, %entry ]384 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop ], [ %start, %entry ], [ %ptr, %loop ]385 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ], [ %i.next, %loop ]386 387 %val = load float, ptr addrspace(7) %ptr.prev388 %sum = fadd float %sum.prev, %val389 390 %ptr = getelementptr float, ptr addrspace(7) %ptr.prev, i32 1391 %i.next = add i32 %i, 1392 %test = icmp ult i32 %i.next, %len393 %test.ext = zext i1 %test to i32394 switch i32 %test.ext, label %loop [395 i32 1, label %loop396 i32 0, label %exit397 ]398exit:399 ret float %sum400}401 402;; And similirly check the "might not be uniform" case.403define float @sum_integer_ops_duplicate_preds(ptr addrspace(8) %buf, i32 %len) {404; CHECK-LABEL: define float @sum_integer_ops_duplicate_preds405; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[LEN:%.*]]) #[[ATTR0]] {406; CHECK-NEXT: entry:407; CHECK-NEXT: br label [[LOOP:%.*]]408; CHECK: loop:409; CHECK-NEXT: [[SUM_PREV:%.*]] = phi float [ [[SUM:%.*]], [[LOOP]] ], [ [[SUM]], [[LOOP]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]410; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ], [ [[I_NEXT]], [[LOOP]] ]411; CHECK-NEXT: [[PTR_PREV_RSRC:%.*]] = phi ptr addrspace(8) [ [[PTR_RSRC:%.*]], [[LOOP]] ], [ [[BUF]], [[ENTRY]] ], [ [[PTR_RSRC]], [[LOOP]] ]412; CHECK-NEXT: [[PTR_PREV_OFF:%.*]] = phi i32 [ [[PTR_OFF:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ], [ [[PTR_OFF]], [[LOOP]] ]413; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[PTR_PREV_RSRC]], i32 [[PTR_PREV_OFF]], i32 0, i32 0)414; CHECK-NEXT: [[SUM]] = fadd float [[SUM_PREV]], [[VAL]]415; CHECK-NEXT: [[PTR_PREV_INT_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[PTR_PREV_RSRC]] to i160416; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i160 [[PTR_PREV_INT_RSRC]], 32417; CHECK-NEXT: [[PTR_PREV_INT_OFF:%.*]] = zext i32 [[PTR_PREV_OFF]] to i160418; CHECK-NEXT: [[PTR_PREV_INT:%.*]] = or i160 [[TMP0]], [[PTR_PREV_INT_OFF]]419; CHECK-NEXT: [[PTR_INT:%.*]] = add i160 [[PTR_PREV_INT]], 4420; CHECK-NEXT: [[TMP1:%.*]] = lshr i160 [[PTR_INT]], 32421; CHECK-NEXT: [[TMP2:%.*]] = trunc i160 [[TMP1]] to i128422; CHECK-NEXT: [[PTR_RSRC]] = inttoptr i128 [[TMP2]] to ptr addrspace(8)423; CHECK-NEXT: [[PTR_OFF]] = trunc i160 [[PTR_INT]] to i32424; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1425; CHECK-NEXT: [[TEST:%.*]] = icmp ult i32 [[I_NEXT]], [[LEN]]426; CHECK-NEXT: [[TEST_EXT:%.*]] = zext i1 [[TEST]] to i32427; CHECK-NEXT: switch i32 [[TEST_EXT]], label [[LOOP]] [428; CHECK-NEXT: i32 1, label [[LOOP]]429; CHECK-NEXT: i32 0, label [[EXIT:%.*]]430; CHECK-NEXT: ]431; CHECK: exit:432; CHECK-NEXT: ret float [[SUM]]433;434entry:435 %start = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)436 br label %loop437loop:438 %sum.prev = phi float [ %sum, %loop ], [ %sum, %loop ], [ 0.0, %entry ]439 %ptr.prev = phi ptr addrspace(7) [ %ptr, %loop ], [ %start, %entry ], [ %ptr, %loop ]440 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ], [ %i.next, %loop ]441 442 %val = load float, ptr addrspace(7) %ptr.prev443 %sum = fadd float %sum.prev, %val444 445 %ptr.prev.int = ptrtoint ptr addrspace(7) %ptr.prev to i160446 %ptr.int = add i160 %ptr.prev.int, 4447 %ptr = inttoptr i160 %ptr.int to ptr addrspace(7)448 %i.next = add i32 %i, 1449 %test = icmp ult i32 %i.next, %len450 %test.ext = zext i1 %test to i32451 switch i32 %test.ext, label %loop [452 i32 1, label %loop453 i32 0, label %exit454 ]455exit:456 ret float %sum457}458 459define void @dominance_not_in_program_order(ptr addrspace(7) inreg %arg) {460; CHECK-LABEL: define void @dominance_not_in_program_order461; CHECK-SAME: ({ ptr addrspace(8), i32 } inreg [[ARG:%.*]]) #[[ATTR0]] {462; CHECK-NEXT: .preheader15:463; CHECK-NEXT: [[ARG_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[ARG]], 0464; CHECK-NEXT: [[ARG_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[ARG]], 1465; CHECK-NEXT: br label [[DOTLR_PH18:%.*]]466; CHECK: .loopexit:467; CHECK-NEXT: [[SCEVGEP12:%.*]] = add i32 [[LSR_IV11_OFF:%.*]], 16468; CHECK-NEXT: br label [[DOTLR_PH18]]469; CHECK: .lr.ph18:470; CHECK-NEXT: [[LSR_IV11_OFF]] = phi i32 [ [[ARG_OFF]], [[DOTLOOPEXIT:%.*]] ], [ [[ARG_OFF]], [[DOTPREHEADER15:%.*]] ]471; CHECK-NEXT: br label [[DOTLOOPEXIT]]472;473.preheader15:474 br label %.lr.ph18475 476.loopexit: ; preds = %.lr.ph18477 %scevgep12 = getelementptr i8, ptr addrspace(7) %lsr.iv11, i32 16478 br label %.lr.ph18479 480.lr.ph18: ; preds = %.loopexit, %.preheader15481 %lsr.iv11 = phi ptr addrspace(7) [ %arg, %.loopexit ], [ %arg, %.preheader15 ]482 br label %.loopexit483}484 485;; iree-org/iree#22551 - crash on something that reduces to the below non-canonical select.486define ptr addrspace(7) @noncanonical_const_cond(ptr addrspace(7) %x) {487; CHECK-LABEL: define { ptr addrspace(8), i32 } @noncanonical_const_cond488; CHECK-SAME: ({ ptr addrspace(8), i32 } [[RET:%.*]]) #[[ATTR0]] {489; CHECK-NEXT: [[X_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[RET]], 0490; CHECK-NEXT: [[X_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[RET]], 1491; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]]492;493 %ret = select i1 false, ptr addrspace(7) %x, ptr addrspace(7) %x494 ret ptr addrspace(7) %ret495}496