1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=infer-address-spaces %s | FileCheck %s 3 4; Make sure memory instructions where the pointer appears in both a 5; pointer and value operand work correctly. 6 7declare void @user(ptr) 8 9; Make sure only the pointer operand use of the store is replaced 10define void @store_flat_pointer_to_self() { 11; CHECK-LABEL: define void @store_flat_pointer_to_self() { 12; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 13; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 14; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 15; CHECK-NEXT: call void @user(ptr [[FLAT]]) 16; CHECK-NEXT: ret void 17; 18 %alloca = alloca ptr, align 8, addrspace(5) 19 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 20 store ptr %flat, ptr %flat, align 8 21 call void @user(ptr %flat) 22 ret void 23} 24 25define void @store_volatile_flat_pointer_to_self() { 26; CHECK-LABEL: define void @store_volatile_flat_pointer_to_self() { 27; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 28; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 29; CHECK-NEXT: store volatile ptr [[FLAT]], ptr [[FLAT]], align 8 30; CHECK-NEXT: call void @user(ptr [[FLAT]]) 31; CHECK-NEXT: ret void 32; 33 %alloca = alloca ptr, align 8, addrspace(5) 34 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 35 store volatile ptr %flat, ptr %flat, align 8 36 call void @user(ptr %flat) 37 ret void 38} 39 40define ptr @atomicrmw_xchg_flat_pointer_to_self() { 41; CHECK-LABEL: define ptr @atomicrmw_xchg_flat_pointer_to_self() { 42; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 43; CHECK-NEXT: [[FLAT1:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 44; CHECK-NEXT: [[XCHG:%.*]] = atomicrmw xchg ptr addrspace(5) [[ALLOCA]], ptr [[FLAT1]] seq_cst, align 8 45; CHECK-NEXT: call void @user(ptr [[FLAT1]]) 46; CHECK-NEXT: ret ptr [[XCHG]] 47; 48 %alloca = alloca ptr, align 8, addrspace(5) 49 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 50 %xchg = atomicrmw xchg ptr %flat, ptr %flat seq_cst, align 8 51 call void @user(ptr %flat) 52 ret ptr %xchg 53} 54 55define ptr @atomicrmw_volatile_xchg_flat_pointer_to_self() { 56; CHECK-LABEL: define ptr @atomicrmw_volatile_xchg_flat_pointer_to_self() { 57; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 58; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 59; CHECK-NEXT: [[XCHG:%.*]] = atomicrmw volatile xchg ptr [[FLAT]], ptr [[FLAT]] seq_cst, align 8 60; CHECK-NEXT: call void @user(ptr [[FLAT]]) 61; CHECK-NEXT: ret ptr [[XCHG]] 62; 63 %alloca = alloca ptr, align 8, addrspace(5) 64 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 65 %xchg = atomicrmw volatile xchg ptr %flat, ptr %flat seq_cst, align 8 66 call void @user(ptr %flat) 67 ret ptr %xchg 68} 69 70define { ptr, i1 } @cmpxchg_flat_pointer_new_to_self(ptr %cmp) { 71; CHECK-LABEL: define { ptr, i1 } @cmpxchg_flat_pointer_new_to_self( 72; CHECK-SAME: ptr [[CMP:%.*]]) { 73; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 74; CHECK-NEXT: [[FLAT1:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 75; CHECK-NEXT: [[CMPX:%.*]] = cmpxchg ptr addrspace(5) [[ALLOCA]], ptr [[CMP]], ptr [[FLAT1]] seq_cst seq_cst, align 8 76; CHECK-NEXT: call void @user(ptr [[FLAT1]]) 77; CHECK-NEXT: ret { ptr, i1 } [[CMPX]] 78; 79 %alloca = alloca ptr, align 8, addrspace(5) 80 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 81 %cmpx = cmpxchg ptr %flat, ptr %cmp, ptr %flat seq_cst seq_cst, align 8 82 call void @user(ptr %flat) 83 ret { ptr, i1 } %cmpx 84} 85 86define { ptr, i1 } @cmpxchg_volatile_flat_pointer_new_to_self(ptr %cmp) { 87; CHECK-LABEL: define { ptr, i1 } @cmpxchg_volatile_flat_pointer_new_to_self( 88; CHECK-SAME: ptr [[CMP:%.*]]) { 89; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 90; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 91; CHECK-NEXT: [[CMPX:%.*]] = cmpxchg volatile ptr [[FLAT]], ptr [[CMP]], ptr [[FLAT]] seq_cst seq_cst, align 8 92; CHECK-NEXT: call void @user(ptr [[FLAT]]) 93; CHECK-NEXT: ret { ptr, i1 } [[CMPX]] 94; 95 %alloca = alloca ptr, align 8, addrspace(5) 96 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 97 %cmpx = cmpxchg volatile ptr %flat, ptr %cmp, ptr %flat seq_cst seq_cst, align 8 98 call void @user(ptr %flat) 99 ret { ptr, i1 } %cmpx 100} 101 102define { ptr, i1 } @volatile_cmpxchg_flat_pointer_new_to_self(ptr %cmp) { 103; CHECK-LABEL: define { ptr, i1 } @volatile_cmpxchg_flat_pointer_new_to_self( 104; CHECK-SAME: ptr [[CMP:%.*]]) { 105; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 106; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 107; CHECK-NEXT: [[CMPX:%.*]] = cmpxchg volatile ptr [[FLAT]], ptr [[CMP]], ptr [[FLAT]] seq_cst seq_cst, align 8 108; CHECK-NEXT: call void @user(ptr [[FLAT]]) 109; CHECK-NEXT: ret { ptr, i1 } [[CMPX]] 110; 111 %alloca = alloca ptr, align 8, addrspace(5) 112 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 113 %cmpx = cmpxchg volatile ptr %flat, ptr %cmp, ptr %flat seq_cst seq_cst, align 8 114 call void @user(ptr %flat) 115 ret { ptr, i1 } %cmpx 116} 117 118define { ptr, i1 } @cmpxchg_flat_pointer_cmp_to_self(ptr %new) { 119; CHECK-LABEL: define { ptr, i1 } @cmpxchg_flat_pointer_cmp_to_self( 120; CHECK-SAME: ptr [[NEW:%.*]]) { 121; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 122; CHECK-NEXT: [[FLAT1:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 123; CHECK-NEXT: [[CMPX:%.*]] = cmpxchg ptr addrspace(5) [[ALLOCA]], ptr [[FLAT1]], ptr [[NEW]] seq_cst seq_cst, align 8 124; CHECK-NEXT: call void @user(ptr [[FLAT1]]) 125; CHECK-NEXT: ret { ptr, i1 } [[CMPX]] 126; 127 %alloca = alloca ptr, align 8, addrspace(5) 128 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 129 %cmpx = cmpxchg ptr %flat, ptr %flat, ptr %new seq_cst seq_cst, align 8 130 call void @user(ptr %flat) 131 ret { ptr, i1 } %cmpx 132} 133 134define { ptr, i1 } @cmpxchg_flat_pointer_cmp_new_self() { 135; CHECK-LABEL: define { ptr, i1 } @cmpxchg_flat_pointer_cmp_new_self() { 136; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 137; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 138; CHECK-NEXT: [[CMPX:%.*]] = cmpxchg ptr addrspace(5) [[ALLOCA]], ptr [[FLAT]], ptr [[FLAT]] seq_cst seq_cst, align 8 139; CHECK-NEXT: call void @user(ptr [[FLAT]]) 140; CHECK-NEXT: ret { ptr, i1 } [[CMPX]] 141; 142 %alloca = alloca ptr, align 8, addrspace(5) 143 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 144 %cmpx = cmpxchg ptr %flat, ptr %flat, ptr %flat seq_cst seq_cst, align 8 145 call void @user(ptr %flat) 146 ret { ptr, i1 } %cmpx 147} 148 149define void @multi_store_flat_pointer_to_self() { 150; CHECK-LABEL: define void @multi_store_flat_pointer_to_self() { 151; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 152; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 153; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 154; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 155; CHECK-NEXT: call void @user(ptr [[FLAT]]) 156; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 157; CHECK-NEXT: store ptr addrspace(5) [[ALLOCA]], ptr addrspace(5) [[ALLOCA]], align 8 158; CHECK-NEXT: ret void 159; 160 %alloca = alloca ptr, align 8, addrspace(5) 161 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 162 store ptr %flat, ptr %flat, align 8 163 store ptr %flat, ptr %flat, align 8 164 call void @user(ptr %flat) 165 store ptr %flat, ptr addrspace(5) %alloca, align 8 166 store ptr addrspace(5) %alloca, ptr %flat, align 8 167 ret void 168} 169 170define void @mixed_volatile_multi_store_flat_pointer_to_self() { 171; CHECK-LABEL: define void @mixed_volatile_multi_store_flat_pointer_to_self() { 172; CHECK-NEXT: [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5) 173; CHECK-NEXT: [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr 174; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 175; CHECK-NEXT: store volatile ptr [[FLAT]], ptr [[FLAT]], align 8 176; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 177; CHECK-NEXT: call void @user(ptr [[FLAT]]) 178; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 179; CHECK-NEXT: store ptr addrspace(5) [[ALLOCA]], ptr addrspace(5) [[ALLOCA]], align 8 180; CHECK-NEXT: store volatile ptr [[FLAT]], ptr [[FLAT]], align 8 181; CHECK-NEXT: store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8 182; CHECK-NEXT: ret void 183; 184 %alloca = alloca ptr, align 8, addrspace(5) 185 %flat = addrspacecast ptr addrspace(5) %alloca to ptr 186 store ptr %flat, ptr %flat, align 8 187 store volatile ptr %flat, ptr %flat, align 8 188 store ptr %flat, ptr %flat, align 8 189 call void @user(ptr %flat) 190 store ptr %flat, ptr addrspace(5) %alloca, align 8 191 store ptr addrspace(5) %alloca, ptr %flat, align 8 192 store volatile ptr %flat, ptr %flat, align 8 193 store ptr %flat, ptr %flat, align 8 194 ret void 195} 196 197define amdgpu_kernel void @uselist_regression_skipped_load(ptr nocapture readonly %Arg, i32 %i) { 198; CHECK-LABEL: define amdgpu_kernel void @uselist_regression_skipped_load( 199; CHECK-SAME: ptr readonly captures(none) [[ARG:%.*]], i32 [[I:%.*]]) { 200; CHECK-NEXT: [[ENTRY:.*:]] 201; CHECK-NEXT: [[ARG_GLOBAL:%.*]] = addrspacecast ptr [[ARG]] to ptr addrspace(1) 202; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds ptr, ptr addrspace(1) [[ARG_GLOBAL]], i32 [[I]] 203; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[P1]] to ptr 204; CHECK-NEXT: [[P2:%.*]] = load volatile ptr, ptr [[TMP0]], align 8 205; CHECK-NEXT: [[P2_GLOBAL:%.*]] = addrspacecast ptr [[P2]] to ptr addrspace(1) 206; CHECK-NEXT: store float 0.000000e+00, ptr addrspace(1) [[P2_GLOBAL]], align 4 207; CHECK-NEXT: ret void 208; 209entry: 210 %Arg.global = addrspacecast ptr %Arg to ptr addrspace(1) 211 %Arg.flat = addrspacecast ptr addrspace(1) %Arg.global to ptr 212 %p1 = getelementptr inbounds ptr, ptr %Arg.flat, i32 %i 213 %p2 = load volatile ptr, ptr %p1, align 8 214 %p2.global = addrspacecast ptr %p2 to ptr addrspace(1) 215 %p2.flat = addrspacecast ptr addrspace(1) %p2.global to ptr 216 store float 0.000000e+00, ptr %p2.flat, align 4 217 ret void 218} 219