1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -infer-address-spaces -instsimplify %s | FileCheck %s 3 4define i8 @ptrmask_cast_local_to_flat(i8 addrspace(3)* %src.ptr, i64 %mask) { 5; CHECK-LABEL: @ptrmask_cast_local_to_flat( 6; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(3)* [[SRC_PTR:%.*]] to i8* 7; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 8; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 9; CHECK-NEXT: ret i8 [[LOAD]] 10; 11 %cast = addrspacecast i8 addrspace(3)* %src.ptr to i8* 12 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 13 %load = load i8, i8* %masked 14 ret i8 %load 15} 16 17define i8 @ptrmask_cast_private_to_flat(i8 addrspace(5)* %src.ptr, i64 %mask) { 18; CHECK-LABEL: @ptrmask_cast_private_to_flat( 19; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(5)* [[SRC_PTR:%.*]] to i8* 20; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 21; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 22; CHECK-NEXT: ret i8 [[LOAD]] 23; 24 %cast = addrspacecast i8 addrspace(5)* %src.ptr to i8* 25 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 26 %load = load i8, i8* %masked 27 ret i8 %load 28} 29 30define i8 @ptrmask_cast_region_to_flat(i8 addrspace(2)* %src.ptr, i64 %mask) { 31; CHECK-LABEL: @ptrmask_cast_region_to_flat( 32; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(2)* [[SRC_PTR:%.*]] to i8* 33; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 34; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 35; CHECK-NEXT: ret i8 [[LOAD]] 36; 37 %cast = addrspacecast i8 addrspace(2)* %src.ptr to i8* 38 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 39 %load = load i8, i8* %masked 40 ret i8 %load 41} 42 43define i8 @ptrmask_cast_global_to_flat(i8 addrspace(1)* %src.ptr, i64 %mask) { 44; CHECK-LABEL: @ptrmask_cast_global_to_flat( 45; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(1)* [[SRC_PTR:%.*]] to i8* 46; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 47; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 48; CHECK-NEXT: ret i8 [[LOAD]] 49; 50 %cast = addrspacecast i8 addrspace(1)* %src.ptr to i8* 51 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 52 %load = load i8, i8* %masked 53 ret i8 %load 54} 55 56define i8 @ptrmask_cast_999_to_flat(i8 addrspace(999)* %src.ptr, i64 %mask) { 57; CHECK-LABEL: @ptrmask_cast_999_to_flat( 58; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(999)* [[SRC_PTR:%.*]] to i8* 59; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 60; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 61; CHECK-NEXT: ret i8 [[LOAD]] 62; 63 %cast = addrspacecast i8 addrspace(999)* %src.ptr to i8* 64 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 65 %load = load i8, i8* %masked 66 ret i8 %load 67} 68 69define i8 @ptrmask_cast_flat_to_local(i8* %ptr, i64 %mask) { 70; CHECK-LABEL: @ptrmask_cast_flat_to_local( 71; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[PTR:%.*]], i64 [[MASK:%.*]]) 72; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8* [[MASKED]] to i8 addrspace(3)* 73; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(3)* [[CAST]], align 1 74; CHECK-NEXT: ret i8 [[LOAD]] 75; 76 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %ptr, i64 %mask) 77 %cast = addrspacecast i8* %masked to i8 addrspace(3)* 78 %load = load i8, i8 addrspace(3)* %cast 79 ret i8 %load 80} 81 82define i8 @ptrmask_cast_flat_to_private(i8* %ptr, i64 %mask) { 83; CHECK-LABEL: @ptrmask_cast_flat_to_private( 84; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[PTR:%.*]], i64 [[MASK:%.*]]) 85; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8* [[MASKED]] to i8 addrspace(5)* 86; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(5)* [[CAST]], align 1 87; CHECK-NEXT: ret i8 [[LOAD]] 88; 89 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %ptr, i64 %mask) 90 %cast = addrspacecast i8* %masked to i8 addrspace(5)* 91 %load = load i8, i8 addrspace(5)* %cast 92 ret i8 %load 93} 94 95define i8 @ptrmask_cast_flat_to_global(i8* %ptr, i64 %mask) { 96; CHECK-LABEL: @ptrmask_cast_flat_to_global( 97; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[PTR:%.*]], i64 [[MASK:%.*]]) 98; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8* [[MASKED]] to i8 addrspace(1)* 99; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(1)* [[CAST]], align 1 100; CHECK-NEXT: ret i8 [[LOAD]] 101; 102 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %ptr, i64 %mask) 103 %cast = addrspacecast i8* %masked to i8 addrspace(1)* 104 %load = load i8, i8 addrspace(1)* %cast 105 ret i8 %load 106} 107 108@lds0 = internal addrspace(3) global i8 123, align 4 109@gv = internal addrspace(1) global i8 123, align 4 110 111define i8 @ptrmask_cast_local_to_flat_global(i64 %mask) { 112; CHECK-LABEL: @ptrmask_cast_local_to_flat_global( 113; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(3)* @lds0 to i8*), i64 [[MASK:%.*]]) 114; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 115; CHECK-NEXT: ret i8 [[LOAD]] 116; 117 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(3)* @lds0 to i8*), i64 %mask) 118 %load = load i8, i8* %masked, align 1 119 ret i8 %load 120} 121 122define i8 @ptrmask_cast_global_to_flat_global(i64 %mask) { 123; CHECK-LABEL: @ptrmask_cast_global_to_flat_global( 124; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(1)* @gv to i8*), i64 [[MASK:%.*]]) 125; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 126; CHECK-NEXT: ret i8 [[LOAD]] 127; 128 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(1)* @gv to i8*), i64 %mask) 129 %load = load i8, i8* %masked, align 1 130 ret i8 %load 131} 132 133define i8 @multi_ptrmask_cast_global_to_flat(i8 addrspace(1)* %src.ptr, i64 %mask) { 134; CHECK-LABEL: @multi_ptrmask_cast_global_to_flat( 135; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(1)* [[SRC_PTR:%.*]] to i8* 136; CHECK-NEXT: [[LOAD0:%.*]] = load i8, i8 addrspace(1)* [[SRC_PTR]], align 1 137; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 138; CHECK-NEXT: [[LOAD1:%.*]] = load i8, i8* [[MASKED]], align 1 139; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD0]], [[LOAD1]] 140; CHECK-NEXT: ret i8 [[ADD]] 141; 142 %cast = addrspacecast i8 addrspace(1)* %src.ptr to i8* 143 %load0 = load i8, i8* %cast 144 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 145 %load1 = load i8, i8* %masked 146 %add = add i8 %load0, %load1 147 ret i8 %add 148} 149 150; Can't rewrite the ptrmask, but can rewrite other use instructions 151define i8 @multi_ptrmask_cast_local_to_flat(i8 addrspace(3)* %src.ptr, i64 %mask) { 152; CHECK-LABEL: @multi_ptrmask_cast_local_to_flat( 153; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(3)* [[SRC_PTR:%.*]] to i8* 154; CHECK-NEXT: [[LOAD0:%.*]] = load i8, i8 addrspace(3)* [[SRC_PTR]], align 1 155; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 156; CHECK-NEXT: [[LOAD1:%.*]] = load i8, i8* [[MASKED]], align 1 157; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD0]], [[LOAD1]] 158; CHECK-NEXT: ret i8 [[ADD]] 159; 160 %cast = addrspacecast i8 addrspace(3)* %src.ptr to i8* 161 %load0 = load i8, i8* %cast 162 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 163 %load1 = load i8, i8* %masked 164 %add = add i8 %load0, %load1 165 ret i8 %add 166} 167 168define i8 @multi_ptrmask_cast_region_to_flat(i8 addrspace(2)* %src.ptr, i64 %mask) { 169; CHECK-LABEL: @multi_ptrmask_cast_region_to_flat( 170; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(2)* [[SRC_PTR:%.*]] to i8* 171; CHECK-NEXT: [[LOAD0:%.*]] = load i8, i8 addrspace(2)* [[SRC_PTR]], align 1 172; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 173; CHECK-NEXT: [[LOAD1:%.*]] = load i8, i8* [[MASKED]], align 1 174; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD0]], [[LOAD1]] 175; CHECK-NEXT: ret i8 [[ADD]] 176; 177 %cast = addrspacecast i8 addrspace(2)* %src.ptr to i8* 178 %load0 = load i8, i8* %cast 179 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 180 %load1 = load i8, i8* %masked 181 %add = add i8 %load0, %load1 182 ret i8 %add 183} 184 185declare i8* @llvm.ptrmask.p0i8.i64(i8*, i64) #0 186declare i8 addrspace(5)* @llvm.ptrmask.p5i8.i32(i8 addrspace(5)*, i32) #0 187declare i8 addrspace(3)* @llvm.ptrmask.p3i8.i32(i8 addrspace(3)*, i32) #0 188declare i8 addrspace(1)* @llvm.ptrmask.p1i8.i64(i8 addrspace(1)*, i64) #0 189 190attributes #0 = { nounwind readnone speculatable willreturn } 191