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: [[TMP1:%.*]] = call i8 addrspace(1)* @llvm.ptrmask.p1i8.i64(i8 addrspace(1)* [[SRC_PTR:%.*]], i64 [[MASK:%.*]]) 46; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(1)* [[TMP1]], align 1 47; CHECK-NEXT: ret i8 [[LOAD]] 48; 49 %cast = addrspacecast i8 addrspace(1)* %src.ptr to i8* 50 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 51 %load = load i8, i8* %masked 52 ret i8 %load 53} 54 55define i8 @ptrmask_cast_999_to_flat(i8 addrspace(999)* %src.ptr, i64 %mask) { 56; CHECK-LABEL: @ptrmask_cast_999_to_flat( 57; CHECK-NEXT: [[TMP1:%.*]] = call i8 addrspace(999)* @llvm.ptrmask.p999i8.i64(i8 addrspace(999)* [[SRC_PTR:%.*]], i64 [[MASK:%.*]]) 58; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(999)* [[TMP1]], align 1 59; CHECK-NEXT: ret i8 [[LOAD]] 60; 61 %cast = addrspacecast i8 addrspace(999)* %src.ptr to i8* 62 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 63 %load = load i8, i8* %masked 64 ret i8 %load 65} 66 67define i8 @ptrmask_cast_flat_to_local(i8* %ptr, i64 %mask) { 68; CHECK-LABEL: @ptrmask_cast_flat_to_local( 69; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[PTR:%.*]], i64 [[MASK:%.*]]) 70; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8* [[MASKED]] to i8 addrspace(3)* 71; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(3)* [[CAST]], align 1 72; CHECK-NEXT: ret i8 [[LOAD]] 73; 74 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %ptr, i64 %mask) 75 %cast = addrspacecast i8* %masked to i8 addrspace(3)* 76 %load = load i8, i8 addrspace(3)* %cast 77 ret i8 %load 78} 79 80define i8 @ptrmask_cast_flat_to_private(i8* %ptr, i64 %mask) { 81; CHECK-LABEL: @ptrmask_cast_flat_to_private( 82; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[PTR:%.*]], i64 [[MASK:%.*]]) 83; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8* [[MASKED]] to i8 addrspace(5)* 84; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(5)* [[CAST]], align 1 85; CHECK-NEXT: ret i8 [[LOAD]] 86; 87 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %ptr, i64 %mask) 88 %cast = addrspacecast i8* %masked to i8 addrspace(5)* 89 %load = load i8, i8 addrspace(5)* %cast 90 ret i8 %load 91} 92 93define i8 @ptrmask_cast_flat_to_global(i8* %ptr, i64 %mask) { 94; CHECK-LABEL: @ptrmask_cast_flat_to_global( 95; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[PTR:%.*]], i64 [[MASK:%.*]]) 96; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8* [[MASKED]] to i8 addrspace(1)* 97; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(1)* [[CAST]], align 1 98; CHECK-NEXT: ret i8 [[LOAD]] 99; 100 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %ptr, i64 %mask) 101 %cast = addrspacecast i8* %masked to i8 addrspace(1)* 102 %load = load i8, i8 addrspace(1)* %cast 103 ret i8 %load 104} 105 106@lds0 = internal addrspace(3) global i8 123, align 4 107@gv = internal addrspace(1) global i8 123, align 4 108 109define i8 @ptrmask_cast_local_to_flat_global(i64 %mask) { 110; CHECK-LABEL: @ptrmask_cast_local_to_flat_global( 111; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(3)* @lds0 to i8*), i64 [[MASK:%.*]]) 112; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8* [[MASKED]], align 1 113; CHECK-NEXT: ret i8 [[LOAD]] 114; 115 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(3)* @lds0 to i8*), i64 %mask) 116 %load = load i8, i8* %masked, align 1 117 ret i8 %load 118} 119 120define i8 @ptrmask_cast_global_to_flat_global(i64 %mask) { 121; CHECK-LABEL: @ptrmask_cast_global_to_flat_global( 122; CHECK-NEXT: [[TMP1:%.*]] = call i8 addrspace(1)* @llvm.ptrmask.p1i8.i64(i8 addrspace(1)* @gv, i64 [[MASK:%.*]]) 123; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(1)* [[TMP1]], align 1 124; CHECK-NEXT: ret i8 [[LOAD]] 125; 126 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* addrspacecast (i8 addrspace(1)* @gv to i8*), i64 %mask) 127 %load = load i8, i8* %masked, align 1 128 ret i8 %load 129} 130 131define i8 @multi_ptrmask_cast_global_to_flat(i8 addrspace(1)* %src.ptr, i64 %mask) { 132; CHECK-LABEL: @multi_ptrmask_cast_global_to_flat( 133; CHECK-NEXT: [[LOAD0:%.*]] = load i8, i8 addrspace(1)* [[SRC_PTR:%.*]], align 1 134; CHECK-NEXT: [[TMP1:%.*]] = call i8 addrspace(1)* @llvm.ptrmask.p1i8.i64(i8 addrspace(1)* [[SRC_PTR]], i64 [[MASK:%.*]]) 135; CHECK-NEXT: [[LOAD1:%.*]] = load i8, i8 addrspace(1)* [[TMP1]], align 1 136; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD0]], [[LOAD1]] 137; CHECK-NEXT: ret i8 [[ADD]] 138; 139 %cast = addrspacecast i8 addrspace(1)* %src.ptr to i8* 140 %load0 = load i8, i8* %cast 141 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 142 %load1 = load i8, i8* %masked 143 %add = add i8 %load0, %load1 144 ret i8 %add 145} 146 147; Can't rewrite the ptrmask, but can rewrite other use instructions 148define i8 @multi_ptrmask_cast_local_to_flat(i8 addrspace(3)* %src.ptr, i64 %mask) { 149; CHECK-LABEL: @multi_ptrmask_cast_local_to_flat( 150; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(3)* [[SRC_PTR:%.*]] to i8* 151; CHECK-NEXT: [[LOAD0:%.*]] = load i8, i8 addrspace(3)* [[SRC_PTR]], align 1 152; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 153; CHECK-NEXT: [[LOAD1:%.*]] = load i8, i8* [[MASKED]], align 1 154; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD0]], [[LOAD1]] 155; CHECK-NEXT: ret i8 [[ADD]] 156; 157 %cast = addrspacecast i8 addrspace(3)* %src.ptr to i8* 158 %load0 = load i8, i8* %cast 159 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 160 %load1 = load i8, i8* %masked 161 %add = add i8 %load0, %load1 162 ret i8 %add 163} 164 165define i8 @multi_ptrmask_cast_region_to_flat(i8 addrspace(2)* %src.ptr, i64 %mask) { 166; CHECK-LABEL: @multi_ptrmask_cast_region_to_flat( 167; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i8 addrspace(2)* [[SRC_PTR:%.*]] to i8* 168; CHECK-NEXT: [[LOAD0:%.*]] = load i8, i8 addrspace(2)* [[SRC_PTR]], align 1 169; CHECK-NEXT: [[MASKED:%.*]] = call i8* @llvm.ptrmask.p0i8.i64(i8* [[CAST]], i64 [[MASK:%.*]]) 170; CHECK-NEXT: [[LOAD1:%.*]] = load i8, i8* [[MASKED]], align 1 171; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD0]], [[LOAD1]] 172; CHECK-NEXT: ret i8 [[ADD]] 173; 174 %cast = addrspacecast i8 addrspace(2)* %src.ptr to i8* 175 %load0 = load i8, i8* %cast 176 %masked = call i8* @llvm.ptrmask.p0i8.i64(i8* %cast, i64 %mask) 177 %load1 = load i8, i8* %masked 178 %add = add i8 %load0, %load1 179 ret i8 %add 180} 181 182declare i8* @llvm.ptrmask.p0i8.i64(i8*, i64) #0 183declare i8 addrspace(5)* @llvm.ptrmask.p5i8.i32(i8 addrspace(5)*, i32) #0 184declare i8 addrspace(3)* @llvm.ptrmask.p3i8.i32(i8 addrspace(3)*, i32) #0 185declare i8 addrspace(1)* @llvm.ptrmask.p1i8.i64(i8 addrspace(1)*, i64) #0 186 187attributes #0 = { nounwind readnone speculatable willreturn } 188