808 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -amdgpu-enable-uniform-intrinsic-combine=0 -O3 -S < %s | FileCheck %s -check-prefix=CURRENT-CHECK3; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -amdgpu-uniform-intrinsic-combine -S < %s | FileCheck %s -check-prefix=PASS-CHECK4; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -passes=amdgpu-uniform-intrinsic-combine -S < %s | FileCheck %s -check-prefix=PASS-CHECK5; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -passes=amdgpu-uniform-intrinsic-combine,dce -S < %s | FileCheck %s -check-prefix=DCE-CHECK6 7define amdgpu_kernel void @permlane64_constant(ptr addrspace(1) %out) {8; CURRENT-CHECK-LABEL: define amdgpu_kernel void @permlane64_constant(9; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {10; CURRENT-CHECK-NEXT: store i32 77, ptr addrspace(1) [[OUT]], align 411; CURRENT-CHECK-NEXT: ret void12;13; PASS-CHECK-LABEL: define amdgpu_kernel void @permlane64_constant(14; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0:[0-9]+]] {15; PASS-CHECK-NEXT: store i32 77, ptr addrspace(1) [[OUT]], align 416; PASS-CHECK-NEXT: ret void17;18; DCE-CHECK-LABEL: define amdgpu_kernel void @permlane64_constant(19; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0:[0-9]+]] {20; DCE-CHECK-NEXT: store i32 77, ptr addrspace(1) [[OUT]], align 421; DCE-CHECK-NEXT: ret void22;23 %v = call i32 @llvm.amdgcn.permlane64(i32 77)24 store i32 %v, ptr addrspace(1) %out25 ret void26}27 28define amdgpu_kernel void @permlane64_uniform(ptr addrspace(1) %out, i32 %src) {29; CURRENT-CHECK-LABEL: define amdgpu_kernel void @permlane64_uniform(30; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]], i32 [[SRC:%.*]]) local_unnamed_addr #[[ATTR0]] {31; CURRENT-CHECK-NEXT: store i32 [[SRC]], ptr addrspace(1) [[OUT]], align 432; CURRENT-CHECK-NEXT: ret void33;34; PASS-CHECK-LABEL: define amdgpu_kernel void @permlane64_uniform(35; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i32 [[SRC:%.*]]) #[[ATTR0]] {36; PASS-CHECK-NEXT: store i32 [[SRC]], ptr addrspace(1) [[OUT]], align 437; PASS-CHECK-NEXT: ret void38;39; DCE-CHECK-LABEL: define amdgpu_kernel void @permlane64_uniform(40; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i32 [[SRC:%.*]]) #[[ATTR0]] {41; DCE-CHECK-NEXT: store i32 [[SRC]], ptr addrspace(1) [[OUT]], align 442; DCE-CHECK-NEXT: ret void43;44 %v = call i32 @llvm.amdgcn.permlane64(i32 %src)45 store i32 %v, ptr addrspace(1) %out46 ret void47}48 49define amdgpu_kernel void @permlane64_nonuniform(i32 addrspace(1)* %out) {50; CURRENT-CHECK-LABEL: define amdgpu_kernel void @permlane64_nonuniform(51; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {52; CURRENT-CHECK-NEXT: [[TID:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()53; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.permlane64.i32(i32 [[TID]])54; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TID]] to i6455; CURRENT-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i64 [[TMP1]]56; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 457; CURRENT-CHECK-NEXT: ret void58;59; PASS-CHECK-LABEL: define amdgpu_kernel void @permlane64_nonuniform(60; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {61; PASS-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()62; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.permlane64.i32(i32 [[TID]])63; PASS-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID]]64; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 465; PASS-CHECK-NEXT: ret void66;67; DCE-CHECK-LABEL: define amdgpu_kernel void @permlane64_nonuniform(68; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {69; DCE-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()70; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.permlane64.i32(i32 [[TID]])71; DCE-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID]]72; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 473; DCE-CHECK-NEXT: ret void74;75 %tid = call i32 @llvm.amdgcn.workitem.id.x()76 %v = call i32 @llvm.amdgcn.permlane64(i32 %tid)77 %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tid78 store i32 %v, i32 addrspace(1)* %out_ptr79 ret void80}81 82define amdgpu_kernel void @permlane64_nonuniform_expression(i32 addrspace(1)* %out) {83; CURRENT-CHECK-LABEL: define amdgpu_kernel void @permlane64_nonuniform_expression(84; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {85; CURRENT-CHECK-NEXT: [[TID:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()86; CURRENT-CHECK-NEXT: [[TID2:%.*]] = add nuw nsw i32 [[TID]], 187; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.permlane64.i32(i32 [[TID2]])88; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TID]] to i6489; CURRENT-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i64 [[TMP1]]90; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 491; CURRENT-CHECK-NEXT: ret void92;93; PASS-CHECK-LABEL: define amdgpu_kernel void @permlane64_nonuniform_expression(94; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {95; PASS-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()96; PASS-CHECK-NEXT: [[TID2:%.*]] = add i32 [[TID]], 197; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.permlane64.i32(i32 [[TID2]])98; PASS-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID]]99; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4100; PASS-CHECK-NEXT: ret void101;102; DCE-CHECK-LABEL: define amdgpu_kernel void @permlane64_nonuniform_expression(103; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {104; DCE-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()105; DCE-CHECK-NEXT: [[TID2:%.*]] = add i32 [[TID]], 1106; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.permlane64.i32(i32 [[TID2]])107; DCE-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID]]108; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4109; DCE-CHECK-NEXT: ret void110;111 %tid = call i32 @llvm.amdgcn.workitem.id.x()112 %tid2 = add i32 %tid, 1113 %v = call i32 @llvm.amdgcn.permlane64(i32 %tid2)114 %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tid115 store i32 %v, i32 addrspace(1)* %out_ptr116 ret void117}118 119define amdgpu_kernel void @readlane_constant(ptr addrspace(1) %out) {120; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_constant(121; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0]] {122; CURRENT-CHECK-NEXT: store i32 7, ptr addrspace(1) [[OUT]], align 4123; CURRENT-CHECK-NEXT: ret void124;125; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_constant(126; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {127; PASS-CHECK-NEXT: store i32 7, ptr addrspace(1) [[OUT]], align 4128; PASS-CHECK-NEXT: ret void129;130; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_constant(131; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {132; DCE-CHECK-NEXT: store i32 7, ptr addrspace(1) [[OUT]], align 4133; DCE-CHECK-NEXT: ret void134;135 %v = call i32 @llvm.amdgcn.readlane(i32 7, i32 5)136 store i32 %v, ptr addrspace(1) %out137 ret void138}139 140define amdgpu_kernel void @readlane_nonuniform_indices(ptr addrspace(1) %out, i32 %src0, i32 %src1) {141; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_indices(142; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]], i32 [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR0]] {143; CURRENT-CHECK-NEXT: store i32 [[SRC0]], ptr addrspace(1) [[OUT]], align 4144; CURRENT-CHECK-NEXT: ret void145;146; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_indices(147; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i32 [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {148; PASS-CHECK-NEXT: store i32 [[SRC0]], ptr addrspace(1) [[OUT]], align 4149; PASS-CHECK-NEXT: ret void150;151; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_indices(152; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i32 [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {153; DCE-CHECK-NEXT: store i32 [[SRC0]], ptr addrspace(1) [[OUT]], align 4154; DCE-CHECK-NEXT: ret void155;156 %v = call i32 @llvm.amdgcn.readlane(i32 %src0, i32 %src1)157 store i32 %v, ptr addrspace(1) %out158 ret void159}160 161define amdgpu_kernel void @readlane_nonuniform_workitem(i32 addrspace(1)* %out) {162; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_workitem(163; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {164; CURRENT-CHECK-NEXT: [[TIDX:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()165; CURRENT-CHECK-NEXT: [[TIDY:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.y()166; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])167; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TIDX]] to i64168; CURRENT-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i64 [[TMP1]]169; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4170; CURRENT-CHECK-NEXT: ret void171;172; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_workitem(173; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {174; PASS-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()175; PASS-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()176; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])177; PASS-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TIDX]]178; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4179; PASS-CHECK-NEXT: ret void180;181; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_workitem(182; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {183; DCE-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()184; DCE-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()185; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])186; DCE-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TIDX]]187; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4188; DCE-CHECK-NEXT: ret void189;190 %tidx = call i32 @llvm.amdgcn.workitem.id.x()191 %tidy = call i32 @llvm.amdgcn.workitem.id.y()192 %v = call i32 @llvm.amdgcn.readlane(i32 %tidx, i32 %tidy)193 %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tidx194 store i32 %v, i32 addrspace(1)* %out_ptr195 ret void196}197 198define amdgpu_kernel void @readlane_nonuniform_expression(i32 addrspace(1)* %out) {199; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_expression(200; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2]] {201; CURRENT-CHECK-NEXT: [[TIDX:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()202; CURRENT-CHECK-NEXT: [[TIDY:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.y()203; CURRENT-CHECK-NEXT: [[TIDX2:%.*]] = add nuw nsw i32 [[TIDX]], 1204; CURRENT-CHECK-NEXT: [[TIDY2:%.*]] = add nuw nsw i32 [[TIDY]], 2205; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX2]], i32 [[TIDY2]])206; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TIDX]] to i64207; CURRENT-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i64 [[TMP1]]208; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4209; CURRENT-CHECK-NEXT: ret void210;211; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_expression(212; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {213; PASS-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()214; PASS-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()215; PASS-CHECK-NEXT: [[TIDX2:%.*]] = add i32 [[TIDX]], 1216; PASS-CHECK-NEXT: [[TIDY2:%.*]] = add i32 [[TIDY]], 2217; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX2]], i32 [[TIDY2]])218; PASS-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TIDX]]219; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4220; PASS-CHECK-NEXT: ret void221;222; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_nonuniform_expression(223; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {224; DCE-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()225; DCE-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()226; DCE-CHECK-NEXT: [[TIDX2:%.*]] = add i32 [[TIDX]], 1227; DCE-CHECK-NEXT: [[TIDY2:%.*]] = add i32 [[TIDY]], 2228; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX2]], i32 [[TIDY2]])229; DCE-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TIDX]]230; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4231; DCE-CHECK-NEXT: ret void232;233 %tidx = call i32 @llvm.amdgcn.workitem.id.x()234 %tidy = call i32 @llvm.amdgcn.workitem.id.y()235 %tidx2 = add i32 %tidx, 1236 %tidy2 = add i32 %tidy, 2237 %v = call i32 @llvm.amdgcn.readlane(i32 %tidx2, i32 %tidy2)238 %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tidx239 store i32 %v, i32 addrspace(1)* %out_ptr240 ret void241}242 243define amdgpu_kernel void @readfirstlane_constant(ptr addrspace(1) %out) {244; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_constant(245; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0]] {246; CURRENT-CHECK-NEXT: store i32 7, ptr addrspace(1) [[OUT]], align 4247; CURRENT-CHECK-NEXT: ret void248;249; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_constant(250; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {251; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 7)252; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4253; PASS-CHECK-NEXT: ret void254;255; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_constant(256; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {257; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 7)258; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4259; DCE-CHECK-NEXT: ret void260;261 %v = call i32 @llvm.amdgcn.readfirstlane(i32 7)262 store i32 %v, ptr addrspace(1) %out263 ret void264}265 266define amdgpu_kernel void @readfirstlane_with_argument(ptr addrspace(1) %out, i32 %src0) {267; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_argument(268; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]], i32 [[SRC0:%.*]]) local_unnamed_addr #[[ATTR0]] {269; CURRENT-CHECK-NEXT: store i32 [[SRC0]], ptr addrspace(1) [[OUT]], align 4270; CURRENT-CHECK-NEXT: ret void271;272; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_argument(273; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i32 [[SRC0:%.*]]) #[[ATTR0]] {274; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[SRC0]])275; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4276; PASS-CHECK-NEXT: ret void277;278; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_argument(279; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i32 [[SRC0:%.*]]) #[[ATTR0]] {280; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[SRC0]])281; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4282; DCE-CHECK-NEXT: ret void283;284 %v = call i32 @llvm.amdgcn.readfirstlane(i32 %src0)285 store i32 %v, ptr addrspace(1) %out286 ret void287}288 289define amdgpu_kernel void @readfirstlane_with_workitem_id(i32 addrspace(1)* %out) {290; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_workitem_id(291; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {292; CURRENT-CHECK-NEXT: [[TID:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()293; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TID]])294; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TID]] to i64295; CURRENT-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i64 [[TMP1]]296; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4297; CURRENT-CHECK-NEXT: ret void298;299; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_workitem_id(300; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {301; PASS-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()302; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TID]])303; PASS-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID]]304; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4305; PASS-CHECK-NEXT: ret void306;307; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_workitem_id(308; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {309; DCE-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()310; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TID]])311; DCE-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID]]312; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4313; DCE-CHECK-NEXT: ret void314;315 %tid = call i32 @llvm.amdgcn.workitem.id.x()316 %v = call i32 @llvm.amdgcn.readfirstlane(i32 %tid)317 %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tid318 store i32 %v, i32 addrspace(1)* %out_ptr319 ret void320}321 322define amdgpu_kernel void @readfirstlane_expression(i32 addrspace(1)* %out) {323; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_expression(324; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {325; CURRENT-CHECK-NEXT: [[TID:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()326; CURRENT-CHECK-NEXT: [[TID2:%.*]] = add nuw nsw i32 [[TID]], 1327; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TID2]])328; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[TID2]] to i64329; CURRENT-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i64 [[TMP1]]330; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4331; CURRENT-CHECK-NEXT: ret void332;333; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_expression(334; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {335; PASS-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()336; PASS-CHECK-NEXT: [[TID2:%.*]] = add i32 [[TID]], 1337; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TID2]])338; PASS-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID2]]339; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4340; PASS-CHECK-NEXT: ret void341;342; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_expression(343; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {344; DCE-CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()345; DCE-CHECK-NEXT: [[TID2:%.*]] = add i32 [[TID]], 1346; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TID2]])347; DCE-CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[OUT]], i32 [[TID2]]348; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT_PTR]], align 4349; DCE-CHECK-NEXT: ret void350;351 %tid = call i32 @llvm.amdgcn.workitem.id.x()352 %tid2 = add i32 %tid, 1353 %v = call i32 @llvm.amdgcn.readfirstlane(i32 %tid2)354 %out_ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %tid2355 store i32 %v, i32 addrspace(1)* %out_ptr356 ret void357}358 359define amdgpu_kernel void @readfirstlane_with_readfirstlane(ptr addrspace(1) %out) {360; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_readfirstlane(361; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0]] {362; CURRENT-CHECK-NEXT: store i32 5, ptr addrspace(1) [[OUT]], align 4363; CURRENT-CHECK-NEXT: ret void364;365; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_readfirstlane(366; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {367; PASS-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 5)368; PASS-CHECK-NEXT: [[V2:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[V1]])369; PASS-CHECK-NEXT: store i32 [[V2]], ptr addrspace(1) [[OUT]], align 4370; PASS-CHECK-NEXT: ret void371;372; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_readfirstlane(373; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {374; DCE-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 5)375; DCE-CHECK-NEXT: [[V2:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[V1]])376; DCE-CHECK-NEXT: store i32 [[V2]], ptr addrspace(1) [[OUT]], align 4377; DCE-CHECK-NEXT: ret void378;379 %v1 = call i32 @llvm.amdgcn.readfirstlane(i32 5)380 %v2 = call i32 @llvm.amdgcn.readfirstlane(i32 %v1)381 store i32 %v2, ptr addrspace(1) %out382 ret void383}384 385define amdgpu_kernel void @readfirstlane_with_readlane(ptr addrspace(1) %out) {386; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_readlane(387; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2]] {388; CURRENT-CHECK-NEXT: [[TIDX:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()389; CURRENT-CHECK-NEXT: [[TIDY:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.y()390; CURRENT-CHECK-NEXT: [[V1:%.*]] = tail call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])391; CURRENT-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4392; CURRENT-CHECK-NEXT: ret void393;394; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_readlane(395; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {396; PASS-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()397; PASS-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()398; PASS-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])399; PASS-CHECK-NEXT: [[V2:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[V1]])400; PASS-CHECK-NEXT: store i32 [[V2]], ptr addrspace(1) [[OUT]], align 4401; PASS-CHECK-NEXT: ret void402;403; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_with_readlane(404; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {405; DCE-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()406; DCE-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()407; DCE-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])408; DCE-CHECK-NEXT: [[V2:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[V1]])409; DCE-CHECK-NEXT: store i32 [[V2]], ptr addrspace(1) [[OUT]], align 4410; DCE-CHECK-NEXT: ret void411;412 %tidx = call i32 @llvm.amdgcn.workitem.id.x()413 %tidy = call i32 @llvm.amdgcn.workitem.id.y()414 %v1 = call i32 @llvm.amdgcn.readlane(i32 %tidx, i32 %tidy)415 %v2 = call i32 @llvm.amdgcn.readfirstlane(i32 %v1)416 store i32 %v2, ptr addrspace(1) %out417 ret void418}419 420define amdgpu_kernel void @readlane_with_firstlane(ptr addrspace(1) %out) {421; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_with_firstlane(422; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {423; CURRENT-CHECK-NEXT: [[TIDX:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()424; CURRENT-CHECK-NEXT: [[V1:%.*]] = tail call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TIDX]])425; CURRENT-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4426; CURRENT-CHECK-NEXT: ret void427;428; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_with_firstlane(429; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {430; PASS-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()431; PASS-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TIDX]])432; PASS-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4433; PASS-CHECK-NEXT: ret void434;435; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_with_firstlane(436; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {437; DCE-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()438; DCE-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[TIDX]])439; DCE-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4440; DCE-CHECK-NEXT: ret void441;442 %tidx = call i32 @llvm.amdgcn.workitem.id.x()443 %v1 = call i32 @llvm.amdgcn.readfirstlane(i32 %tidx)444 %v2 = call i32 @llvm.amdgcn.readlane(i32 %v1, i32 3)445 store i32 %v2, ptr addrspace(1) %out446 ret void447}448 449define amdgpu_kernel void @readlane_readlane(ptr addrspace(1) %out) {450; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_readlane(451; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2]] {452; CURRENT-CHECK-NEXT: [[TIDX:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()453; CURRENT-CHECK-NEXT: [[TIDY:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.y()454; CURRENT-CHECK-NEXT: [[V1:%.*]] = tail call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])455; CURRENT-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4456; CURRENT-CHECK-NEXT: ret void457;458; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_readlane(459; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {460; PASS-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()461; PASS-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()462; PASS-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])463; PASS-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4464; PASS-CHECK-NEXT: ret void465;466; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_readlane(467; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {468; DCE-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()469; DCE-CHECK-NEXT: [[TIDY:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()470; DCE-CHECK-NEXT: [[V1:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])471; DCE-CHECK-NEXT: store i32 [[V1]], ptr addrspace(1) [[OUT]], align 4472; DCE-CHECK-NEXT: ret void473;474 %tidx = call i32 @llvm.amdgcn.workitem.id.x()475 %tidy = call i32 @llvm.amdgcn.workitem.id.y()476 %v1 = call i32 @llvm.amdgcn.readlane(i32 %tidx, i32 %tidy)477 %v2 = call i32 @llvm.amdgcn.readlane(i32 %v1, i32 2)478 store i32 %v2, ptr addrspace(1) %out479 ret void480}481 482 483define amdgpu_kernel void @permlane64_boundary(ptr addrspace(1) %out_min, ptr addrspace(1) %out_max) {484; CURRENT-CHECK-LABEL: define amdgpu_kernel void @permlane64_boundary(485; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT_MIN:%.*]], ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT_MAX:%.*]]) local_unnamed_addr #[[ATTR0]] {486; CURRENT-CHECK-NEXT: store i32 -2147483648, ptr addrspace(1) [[OUT_MIN]], align 4487; CURRENT-CHECK-NEXT: store i32 2147483647, ptr addrspace(1) [[OUT_MAX]], align 4488; CURRENT-CHECK-NEXT: ret void489;490; PASS-CHECK-LABEL: define amdgpu_kernel void @permlane64_boundary(491; PASS-CHECK-SAME: ptr addrspace(1) [[OUT_MIN:%.*]], ptr addrspace(1) [[OUT_MAX:%.*]]) #[[ATTR0]] {492; PASS-CHECK-NEXT: store i32 -2147483648, ptr addrspace(1) [[OUT_MIN]], align 4493; PASS-CHECK-NEXT: store i32 2147483647, ptr addrspace(1) [[OUT_MAX]], align 4494; PASS-CHECK-NEXT: ret void495;496; DCE-CHECK-LABEL: define amdgpu_kernel void @permlane64_boundary(497; DCE-CHECK-SAME: ptr addrspace(1) [[OUT_MIN:%.*]], ptr addrspace(1) [[OUT_MAX:%.*]]) #[[ATTR0]] {498; DCE-CHECK-NEXT: store i32 -2147483648, ptr addrspace(1) [[OUT_MIN]], align 4499; DCE-CHECK-NEXT: store i32 2147483647, ptr addrspace(1) [[OUT_MAX]], align 4500; DCE-CHECK-NEXT: ret void501;502 %min_v = call i32 @llvm.amdgcn.permlane64(i32 -2147483648)503 store i32 %min_v, ptr addrspace(1) %out_min504 %max_v = call i32 @llvm.amdgcn.permlane64(i32 2147483647)505 store i32 %max_v, ptr addrspace(1) %out_max506 ret void507}508 509define amdgpu_kernel void @readlane_cross_lane(ptr addrspace(1) %out) {510; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_cross_lane(511; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {512; CURRENT-CHECK-NEXT: [[TIDX:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()513; CURRENT-CHECK-NEXT: [[TIDY:%.*]] = add nuw nsw i32 [[TIDX]], 5514; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])515; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4516; CURRENT-CHECK-NEXT: ret void517;518; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_cross_lane(519; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {520; PASS-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()521; PASS-CHECK-NEXT: [[TIDY:%.*]] = add i32 [[TIDX]], 5522; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])523; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4524; PASS-CHECK-NEXT: ret void525;526; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_cross_lane(527; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {528; DCE-CHECK-NEXT: [[TIDX:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()529; DCE-CHECK-NEXT: [[TIDY:%.*]] = add i32 [[TIDX]], 5530; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[TIDX]], i32 [[TIDY]])531; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4532; DCE-CHECK-NEXT: ret void533;534 %tidx = call i32 @llvm.amdgcn.workitem.id.x()535 %tidy = add i32 %tidx, 5536 %v = call i32 @llvm.amdgcn.readlane(i32 %tidx, i32 %tidy)537 store i32 %v, ptr addrspace(1) %out538 ret void539}540 541define amdgpu_kernel void @readfirstlane_random(ptr addrspace(1) %out) {542; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_random(543; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0]] {544; CURRENT-CHECK-NEXT: store i32 435, ptr addrspace(1) [[OUT]], align 4545; CURRENT-CHECK-NEXT: ret void546;547; PASS-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_random(548; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {549; PASS-CHECK-NEXT: [[RANDOM:%.*]] = xor i32 123, 456550; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[RANDOM]])551; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4552; PASS-CHECK-NEXT: ret void553;554; DCE-CHECK-LABEL: define amdgpu_kernel void @readfirstlane_random(555; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {556; DCE-CHECK-NEXT: [[RANDOM:%.*]] = xor i32 123, 456557; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[RANDOM]])558; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4559; DCE-CHECK-NEXT: ret void560;561 %random = xor i32 123, 456562 %v = call i32 @llvm.amdgcn.readfirstlane(i32 %random)563 store i32 %v, ptr addrspace(1) %out564 ret void565}566 567define amdgpu_kernel void @readlane_expression(ptr addrspace(1) %out) {568; CURRENT-CHECK-LABEL: define amdgpu_kernel void @readlane_expression(569; CURRENT-CHECK-SAME: ptr addrspace(1) writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {570; CURRENT-CHECK-NEXT: [[IDX1:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()571; CURRENT-CHECK-NEXT: [[IDX2:%.*]] = shl nuw nsw i32 [[IDX1]], 1572; CURRENT-CHECK-NEXT: [[V:%.*]] = tail call i32 @llvm.amdgcn.readlane.i32(i32 [[IDX1]], i32 [[IDX2]])573; CURRENT-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4574; CURRENT-CHECK-NEXT: ret void575;576; PASS-CHECK-LABEL: define amdgpu_kernel void @readlane_expression(577; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {578; PASS-CHECK-NEXT: [[IDX1:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()579; PASS-CHECK-NEXT: [[IDX2:%.*]] = mul i32 [[IDX1]], 2580; PASS-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[IDX1]], i32 [[IDX2]])581; PASS-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4582; PASS-CHECK-NEXT: ret void583;584; DCE-CHECK-LABEL: define amdgpu_kernel void @readlane_expression(585; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {586; DCE-CHECK-NEXT: [[IDX1:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()587; DCE-CHECK-NEXT: [[IDX2:%.*]] = mul i32 [[IDX1]], 2588; DCE-CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[IDX1]], i32 [[IDX2]])589; DCE-CHECK-NEXT: store i32 [[V]], ptr addrspace(1) [[OUT]], align 4590; DCE-CHECK-NEXT: ret void591;592 %idx1 = call i32 @llvm.amdgcn.workitem.id.x()593 %idx2 = mul i32 %idx1, 2594 %v = call i32 @llvm.amdgcn.readlane(i32 %idx1, i32 %idx2)595 store i32 %v, ptr addrspace(1) %out596 ret void597}598 599define amdgpu_kernel void @ballot_i32(i32 %v, ptr addrspace(1) %out) {600; CURRENT-CHECK-LABEL: define amdgpu_kernel void @ballot_i32(601; CURRENT-CHECK-SAME: i32 [[V:%.*]], ptr addrspace(1) writeonly captures(none) initializes((0, 1)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {602; CURRENT-CHECK-NEXT: [[C:%.*]] = trunc i32 [[V]] to i1603; CURRENT-CHECK-NEXT: [[BALLOT:%.*]] = tail call i32 @llvm.amdgcn.ballot.i32(i1 [[C]])604; CURRENT-CHECK-NEXT: [[BALLOT_NE_ZERO:%.*]] = icmp ne i32 [[BALLOT]], 0605; CURRENT-CHECK-NEXT: store i1 [[BALLOT_NE_ZERO]], ptr addrspace(1) [[OUT]], align 1606; CURRENT-CHECK-NEXT: ret void607;608; PASS-CHECK-LABEL: define amdgpu_kernel void @ballot_i32(609; PASS-CHECK-SAME: i32 [[V:%.*]], ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {610; PASS-CHECK-NEXT: [[C:%.*]] = trunc i32 [[V]] to i1611; PASS-CHECK-NEXT: [[BALLOT:%.*]] = call i32 @llvm.amdgcn.ballot.i32(i1 [[C]])612; PASS-CHECK-NEXT: [[BALLOT_NE_ZERO:%.*]] = icmp ne i32 [[BALLOT]], 0613; PASS-CHECK-NEXT: store i1 [[C]], ptr addrspace(1) [[OUT]], align 1614; PASS-CHECK-NEXT: ret void615;616; DCE-CHECK-LABEL: define amdgpu_kernel void @ballot_i32(617; DCE-CHECK-SAME: i32 [[V:%.*]], ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {618; DCE-CHECK-NEXT: [[C:%.*]] = trunc i32 [[V]] to i1619; DCE-CHECK-NEXT: store i1 [[C]], ptr addrspace(1) [[OUT]], align 1620; DCE-CHECK-NEXT: ret void621;622 %c = trunc i32 %v to i1623 %ballot = call i32 @llvm.amdgcn.ballot.i32(i1 %c)624 %ballot_ne_zero = icmp ne i32 %ballot, 0625 store i1 %ballot_ne_zero, ptr addrspace(1) %out626 ret void627}628 629define amdgpu_kernel void @ballot_i64(i32 %v, ptr addrspace(1) %out) {630; CURRENT-CHECK-LABEL: define amdgpu_kernel void @ballot_i64(631; CURRENT-CHECK-SAME: i32 [[V:%.*]], ptr addrspace(1) writeonly captures(none) initializes((0, 1)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] {632; CURRENT-CHECK-NEXT: [[C:%.*]] = trunc i32 [[V]] to i1633; CURRENT-CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.amdgcn.ballot.i32(i1 [[C]])634; CURRENT-CHECK-NEXT: [[BALLOT_NE_ZERO:%.*]] = icmp ne i32 [[TMP1]], 0635; CURRENT-CHECK-NEXT: store i1 [[BALLOT_NE_ZERO]], ptr addrspace(1) [[OUT]], align 1636; CURRENT-CHECK-NEXT: ret void637;638; PASS-CHECK-LABEL: define amdgpu_kernel void @ballot_i64(639; PASS-CHECK-SAME: i32 [[V:%.*]], ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {640; PASS-CHECK-NEXT: [[C:%.*]] = trunc i32 [[V]] to i1641; PASS-CHECK-NEXT: [[BALLOT:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 [[C]])642; PASS-CHECK-NEXT: [[BALLOT_NE_ZERO:%.*]] = icmp ne i64 [[BALLOT]], 0643; PASS-CHECK-NEXT: store i1 [[C]], ptr addrspace(1) [[OUT]], align 1644; PASS-CHECK-NEXT: ret void645;646; DCE-CHECK-LABEL: define amdgpu_kernel void @ballot_i64(647; DCE-CHECK-SAME: i32 [[V:%.*]], ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {648; DCE-CHECK-NEXT: [[C:%.*]] = trunc i32 [[V]] to i1649; DCE-CHECK-NEXT: store i1 [[C]], ptr addrspace(1) [[OUT]], align 1650; DCE-CHECK-NEXT: ret void651;652 %c = trunc i32 %v to i1653 %ballot = call i64 @llvm.amdgcn.ballot.i64(i1 %c)654 %ballot_ne_zero = icmp ne i64 %ballot, 0655 store i1 %ballot_ne_zero, ptr addrspace(1) %out656 ret void657}658 659define amdgpu_kernel void @test_readlane_i16(i16 %src0, i32 %src1) {660; CURRENT-CHECK-LABEL: define amdgpu_kernel void @test_readlane_i16(661; CURRENT-CHECK-SAME: i16 [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {662; CURRENT-CHECK-NEXT: tail call void asm sideeffect "663; CURRENT-CHECK-NEXT: ret void664;665; PASS-CHECK-LABEL: define amdgpu_kernel void @test_readlane_i16(666; PASS-CHECK-SAME: i16 [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {667; PASS-CHECK-NEXT: call void asm sideeffect "668; PASS-CHECK-NEXT: ret void669;670; DCE-CHECK-LABEL: define amdgpu_kernel void @test_readlane_i16(671; DCE-CHECK-SAME: i16 [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {672; DCE-CHECK-NEXT: call void asm sideeffect "673; DCE-CHECK-NEXT: ret void674;675 %readlane = call i16 @llvm.amdgcn.readlane.i16(i16 %src0, i32 %src1)676 call void asm sideeffect "; use $0", "s"(i16 %readlane)677 ret void678}679 680define amdgpu_kernel void @test_readlane_i64(i64 %src0, i32 %src1) {681; CURRENT-CHECK-LABEL: define amdgpu_kernel void @test_readlane_i64(682; CURRENT-CHECK-SAME: i64 [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3]] {683; CURRENT-CHECK-NEXT: tail call void asm sideeffect "684; CURRENT-CHECK-NEXT: ret void685;686; PASS-CHECK-LABEL: define amdgpu_kernel void @test_readlane_i64(687; PASS-CHECK-SAME: i64 [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {688; PASS-CHECK-NEXT: call void asm sideeffect "689; PASS-CHECK-NEXT: ret void690;691; DCE-CHECK-LABEL: define amdgpu_kernel void @test_readlane_i64(692; DCE-CHECK-SAME: i64 [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {693; DCE-CHECK-NEXT: call void asm sideeffect "694; DCE-CHECK-NEXT: ret void695;696 %readlane = call i64 @llvm.amdgcn.readlane.i64(i64 %src0, i32 %src1)697 call void asm sideeffect "; use $0", "s"(i64 %readlane)698 ret void699}700 701define amdgpu_kernel void @test_readlane_bf16(bfloat %src0, i32 %src1) {702; CURRENT-CHECK-LABEL: define amdgpu_kernel void @test_readlane_bf16(703; CURRENT-CHECK-SAME: bfloat [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3]] {704; CURRENT-CHECK-NEXT: tail call void asm sideeffect "705; CURRENT-CHECK-NEXT: ret void706;707; PASS-CHECK-LABEL: define amdgpu_kernel void @test_readlane_bf16(708; PASS-CHECK-SAME: bfloat [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {709; PASS-CHECK-NEXT: call void asm sideeffect "710; PASS-CHECK-NEXT: ret void711;712; DCE-CHECK-LABEL: define amdgpu_kernel void @test_readlane_bf16(713; DCE-CHECK-SAME: bfloat [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {714; DCE-CHECK-NEXT: call void asm sideeffect "715; DCE-CHECK-NEXT: ret void716;717 %readlane = call bfloat @llvm.amdgcn.readlane.bf16(bfloat %src0, i32 %src1)718 call void asm sideeffect "; use $0", "s"(bfloat %readlane)719 ret void720}721 722define amdgpu_kernel void @test_readlane_f16(half %src0, i32 %src1) {723; CURRENT-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f16(724; CURRENT-CHECK-SAME: half [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3]] {725; CURRENT-CHECK-NEXT: tail call void asm sideeffect "726; CURRENT-CHECK-NEXT: ret void727;728; PASS-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f16(729; PASS-CHECK-SAME: half [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {730; PASS-CHECK-NEXT: call void asm sideeffect "731; PASS-CHECK-NEXT: ret void732;733; DCE-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f16(734; DCE-CHECK-SAME: half [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {735; DCE-CHECK-NEXT: call void asm sideeffect "736; DCE-CHECK-NEXT: ret void737;738 %readlane = call half @llvm.amdgcn.readlane.f16(half %src0, i32 %src1)739 call void asm sideeffect "; use $0", "s"(half %readlane)740 ret void741}742 743define amdgpu_kernel void @test_readlane_f32(float %src0, i32 %src1) {744; CURRENT-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f32(745; CURRENT-CHECK-SAME: float [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3]] {746; CURRENT-CHECK-NEXT: tail call void asm sideeffect "747; CURRENT-CHECK-NEXT: ret void748;749; PASS-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f32(750; PASS-CHECK-SAME: float [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {751; PASS-CHECK-NEXT: call void asm sideeffect "752; PASS-CHECK-NEXT: ret void753;754; DCE-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f32(755; DCE-CHECK-SAME: float [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {756; DCE-CHECK-NEXT: call void asm sideeffect "757; DCE-CHECK-NEXT: ret void758;759 %readlane = call float @llvm.amdgcn.readlane.f32(float %src0, i32 %src1)760 call void asm sideeffect "; use $0", "s"(float %readlane)761 ret void762}763 764define amdgpu_kernel void @test_readlane_f64(double %src0, i32 %src1) {765; CURRENT-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f64(766; CURRENT-CHECK-SAME: double [[SRC0:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3]] {767; CURRENT-CHECK-NEXT: tail call void asm sideeffect "768; CURRENT-CHECK-NEXT: ret void769;770; PASS-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f64(771; PASS-CHECK-SAME: double [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {772; PASS-CHECK-NEXT: call void asm sideeffect "773; PASS-CHECK-NEXT: ret void774;775; DCE-CHECK-LABEL: define amdgpu_kernel void @test_readlane_f64(776; DCE-CHECK-SAME: double [[SRC0:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {777; DCE-CHECK-NEXT: call void asm sideeffect "778; DCE-CHECK-NEXT: ret void779;780 %readlane = call double @llvm.amdgcn.readlane.f64(double %src0, i32 %src1)781 call void asm sideeffect "; use $0", "s"(double %readlane)782 ret void783}784; All such cases can be optimised, given generic way to query getDeclarationIfExists()785define void @test_readlane_v8i16(ptr addrspace(1) %out, <8 x i16> %src, i32 %src1) {786; CURRENT-CHECK-LABEL: define void @test_readlane_v8i16(787; CURRENT-CHECK-SAME: ptr addrspace(1) readnone captures(none) [[OUT:%.*]], <8 x i16> [[SRC:%.*]], i32 [[SRC1:%.*]]) local_unnamed_addr #[[ATTR3]] {788; CURRENT-CHECK-NEXT: [[X:%.*]] = tail call <8 x i16> @llvm.amdgcn.readlane.v8i16(<8 x i16> [[SRC]], i32 [[SRC1]])789; CURRENT-CHECK-NEXT: tail call void asm sideeffect "790; CURRENT-CHECK-NEXT: ret void791;792; PASS-CHECK-LABEL: define void @test_readlane_v8i16(793; PASS-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], <8 x i16> [[SRC:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {794; PASS-CHECK-NEXT: [[X:%.*]] = call <8 x i16> @llvm.amdgcn.readlane.v8i16(<8 x i16> [[SRC]], i32 [[SRC1]])795; PASS-CHECK-NEXT: call void asm sideeffect "796; PASS-CHECK-NEXT: ret void797;798; DCE-CHECK-LABEL: define void @test_readlane_v8i16(799; DCE-CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], <8 x i16> [[SRC:%.*]], i32 [[SRC1:%.*]]) #[[ATTR0]] {800; DCE-CHECK-NEXT: [[X:%.*]] = call <8 x i16> @llvm.amdgcn.readlane.v8i16(<8 x i16> [[SRC]], i32 [[SRC1]])801; DCE-CHECK-NEXT: call void asm sideeffect "802; DCE-CHECK-NEXT: ret void803;804 %x = call <8 x i16> @llvm.amdgcn.readlane.v8i16(<8 x i16> %src, i32 %src1)805 call void asm sideeffect "; use $0", "s"(<8 x i16> %x)806 ret void807}808