147 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-lower-module-lds < %s --amdgpu-lower-module-lds-strategy=module | FileCheck -check-prefixes=CHECK,MODULE %s3; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-lower-module-lds < %s --amdgpu-lower-module-lds-strategy=table | FileCheck -check-prefixes=CHECK,TABLE %s4; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-lower-module-lds < %s --amdgpu-lower-module-lds-strategy=kernel | FileCheck -check-prefixes=CHECK,K_OR_HY %s5; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-lower-module-lds < %s --amdgpu-lower-module-lds-strategy=hybrid | FileCheck -check-prefixes=CHECK,K_OR_HY %s6 7;; Same checks for kernel and for hybrid as an unambiguous reference to a variable - one where exactly one kernel8;; can reach it - is the case where hybrid lowering can always prefer the direct access.9 10;; Single kernel is sole user of single variable, all options codegen as direct access to kernel struct11 12@k0.lds = addrspace(3) global i8 poison13define amdgpu_kernel void @k0() {14; CHECK-LABEL: @k0(15; CHECK-NEXT: [[LD:%.*]] = load i8, ptr addrspace(3) @llvm.amdgcn.kernel.k0.lds, align 116; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[LD]], 217; CHECK-NEXT: store i8 [[MUL]], ptr addrspace(3) @llvm.amdgcn.kernel.k0.lds, align 118; CHECK-NEXT: ret void19;20 %ld = load i8, ptr addrspace(3) @k0.lds21 %mul = mul i8 %ld, 222 store i8 %mul, ptr addrspace(3) @k0.lds23 ret void24}25 26;; Function is reachable from one kernel. Variable goes in module lds or the kernel struct, but never both.27 28@f0.lds = addrspace(3) global i16 poison29define void @f0() {30; MODULE-LABEL: @f0(31; MODULE-NEXT: [[LD:%.*]] = load i16, ptr addrspace(3) getelementptr inbounds ([[LLVM_AMDGCN_MODULE_LDS_T:%.*]], ptr addrspace(3) @llvm.amdgcn.module.lds, i32 0, i32 1), align 4, !alias.scope [[META1:![0-9]+]], !noalias [[META4:![0-9]+]]32; MODULE-NEXT: [[MUL:%.*]] = mul i16 [[LD]], 333; MODULE-NEXT: store i16 [[MUL]], ptr addrspace(3) getelementptr inbounds ([[LLVM_AMDGCN_MODULE_LDS_T]], ptr addrspace(3) @llvm.amdgcn.module.lds, i32 0, i32 1), align 4, !alias.scope [[META1]], !noalias [[META4]]34; MODULE-NEXT: ret void35;36; TABLE-LABEL: @f0(37; TABLE-NEXT: [[TMP1:%.*]] = call i32 @llvm.amdgcn.lds.kernel.id()38; TABLE-NEXT: [[F0_LDS2:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr addrspace(4) @llvm.amdgcn.lds.offset.table, i32 0, i32 [[TMP1]], i32 139; TABLE-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(4) [[F0_LDS2]], align 440; TABLE-NEXT: [[F0_LDS3:%.*]] = inttoptr i32 [[TMP2]] to ptr addrspace(3)41; TABLE-NEXT: [[LD:%.*]] = load i16, ptr addrspace(3) [[F0_LDS3]], align 242; TABLE-NEXT: [[MUL:%.*]] = mul i16 [[LD]], 343; TABLE-NEXT: [[F0_LDS:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr addrspace(4) @llvm.amdgcn.lds.offset.table, i32 0, i32 [[TMP1]], i32 144; TABLE-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[F0_LDS]], align 445; TABLE-NEXT: [[F0_LDS1:%.*]] = inttoptr i32 [[TMP3]] to ptr addrspace(3)46; TABLE-NEXT: store i16 [[MUL]], ptr addrspace(3) [[F0_LDS1]], align 247; TABLE-NEXT: ret void48;49; K_OR_HY-LABEL: @f0(50; K_OR_HY-NEXT: [[LD:%.*]] = load i16, ptr addrspace(3) @llvm.amdgcn.kernel.k_f0.lds, align 251; K_OR_HY-NEXT: [[MUL:%.*]] = mul i16 [[LD]], 352; K_OR_HY-NEXT: store i16 [[MUL]], ptr addrspace(3) @llvm.amdgcn.kernel.k_f0.lds, align 253; K_OR_HY-NEXT: ret void54;55 %ld = load i16, ptr addrspace(3) @f0.lds56 %mul = mul i16 %ld, 357 store i16 %mul, ptr addrspace(3) @f0.lds58 ret void59}60 61define amdgpu_kernel void @k_f0() {62; MODULE-LABEL: @k_f0(63; MODULE-NEXT: call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.module.lds) ], !alias.scope [[META10:![0-9]+]], !noalias [[META1]]64; MODULE-NEXT: call void @f0()65; MODULE-NEXT: ret void66;67; TABLE-LABEL: @k_f0(68; TABLE-NEXT: call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.kernel.k_f0.lds) ]69; TABLE-NEXT: call void @f0()70; TABLE-NEXT: ret void71;72; K_OR_HY-LABEL: @k_f0(73; K_OR_HY-NEXT: call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.kernel.k_f0.lds) ]74; K_OR_HY-NEXT: call void @f0()75; K_OR_HY-NEXT: ret void76;77 call void @f0()78 ret void79}80 81;; As above, but with the kernel also uing the variable.82 83@both.lds = addrspace(3) global i32 poison84define void @f_both() {85; MODULE-LABEL: @f_both(86; MODULE-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) @llvm.amdgcn.module.lds, align 4, !alias.scope [[META10]], !noalias [[META11:![0-9]+]]87; MODULE-NEXT: [[MUL:%.*]] = mul i32 [[LD]], 488; MODULE-NEXT: store i32 [[MUL]], ptr addrspace(3) @llvm.amdgcn.module.lds, align 4, !alias.scope [[META10]], !noalias [[META11]]89; MODULE-NEXT: ret void90;91; TABLE-LABEL: @f_both(92; TABLE-NEXT: [[TMP1:%.*]] = call i32 @llvm.amdgcn.lds.kernel.id()93; TABLE-NEXT: [[BOTH_LDS2:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr addrspace(4) @llvm.amdgcn.lds.offset.table, i32 0, i32 [[TMP1]], i32 094; TABLE-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(4) [[BOTH_LDS2]], align 495; TABLE-NEXT: [[BOTH_LDS3:%.*]] = inttoptr i32 [[TMP2]] to ptr addrspace(3)96; TABLE-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) [[BOTH_LDS3]], align 497; TABLE-NEXT: [[MUL:%.*]] = mul i32 [[LD]], 498; TABLE-NEXT: [[BOTH_LDS:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr addrspace(4) @llvm.amdgcn.lds.offset.table, i32 0, i32 [[TMP1]], i32 099; TABLE-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[BOTH_LDS]], align 4100; TABLE-NEXT: [[BOTH_LDS1:%.*]] = inttoptr i32 [[TMP3]] to ptr addrspace(3)101; TABLE-NEXT: store i32 [[MUL]], ptr addrspace(3) [[BOTH_LDS1]], align 4102; TABLE-NEXT: ret void103;104; K_OR_HY-LABEL: @f_both(105; K_OR_HY-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds, align 4106; K_OR_HY-NEXT: [[MUL:%.*]] = mul i32 [[LD]], 4107; K_OR_HY-NEXT: store i32 [[MUL]], ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds, align 4108; K_OR_HY-NEXT: ret void109;110 %ld = load i32, ptr addrspace(3) @both.lds111 %mul = mul i32 %ld, 4112 store i32 %mul, ptr addrspace(3) @both.lds113 ret void114}115 116define amdgpu_kernel void @k0_both() {117; MODULE-LABEL: @k0_both(118; MODULE-NEXT: call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.module.lds) ]119; MODULE-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) @llvm.amdgcn.module.lds, align 4, !alias.scope [[META10]], !noalias [[META1]]120; MODULE-NEXT: [[MUL:%.*]] = mul i32 [[LD]], 5121; MODULE-NEXT: store i32 [[MUL]], ptr addrspace(3) @llvm.amdgcn.module.lds, align 4, !alias.scope [[META10]], !noalias [[META1]]122; MODULE-NEXT: call void @f_both()123; MODULE-NEXT: ret void124;125; TABLE-LABEL: @k0_both(126; TABLE-NEXT: call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds) ]127; TABLE-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds, align 4128; TABLE-NEXT: [[MUL:%.*]] = mul i32 [[LD]], 5129; TABLE-NEXT: store i32 [[MUL]], ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds, align 4130; TABLE-NEXT: call void @f_both()131; TABLE-NEXT: ret void132;133; K_OR_HY-LABEL: @k0_both(134; K_OR_HY-NEXT: call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds) ]135; K_OR_HY-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds, align 4136; K_OR_HY-NEXT: [[MUL:%.*]] = mul i32 [[LD]], 5137; K_OR_HY-NEXT: store i32 [[MUL]], ptr addrspace(3) @llvm.amdgcn.kernel.k0_both.lds, align 4138; K_OR_HY-NEXT: call void @f_both()139; K_OR_HY-NEXT: ret void140;141 %ld = load i32, ptr addrspace(3) @both.lds142 %mul = mul i32 %ld, 5143 store i32 %mul, ptr addrspace(3) @both.lds144 call void @f_both()145 ret void146}147