189 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -mcpu=gfx900 -amdgpu-lower-buffer-fat-pointers < %s | FileCheck %s3; RUN: opt -S -mcpu=gfx900 -passes=amdgpu-lower-buffer-fat-pointers < %s | FileCheck %s4 5target triple = "amdgcn--"6 7define void @loads(ptr addrspace(8) %buf) {8; CHECK-LABEL: define void @loads9; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]]) #[[ATTR0:[0-9]+]] {10; CHECK-NEXT: [[SCALAR:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)11; CHECK-NEXT: [[VEC2:%.*]] = call <2 x float> @llvm.amdgcn.raw.ptr.buffer.load.v2f32(ptr addrspace(8) align 8 [[BUF]], i32 16, i32 0, i32 0)12; CHECK-NEXT: [[VEC4:%.*]] = call <4 x float> @llvm.amdgcn.raw.ptr.buffer.load.v4f32(ptr addrspace(8) align 16 [[BUF]], i32 16, i32 0, i32 0)13; CHECK-NEXT: [[NONTEMPORAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0), !nontemporal [[META0:![0-9]+]]14; CHECK-NEXT: [[INVARIANT:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0), !invariant.load [[META1:![0-9]+]]15; CHECK-NEXT: [[NONTEMPORAL_INVARIANT:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0), !invariant.load [[META1]], !nontemporal [[META0]]16; CHECK-NEXT: [[VOLATILE:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648)17; CHECK-NEXT: [[VOLATILE_NONTEMPORAL:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648), !nontemporal [[META0]]18; CHECK-NEXT: fence syncscope("wavefront") release19; CHECK-NEXT: [[ATOMIC:%.*]] = call float @llvm.amdgcn.raw.ptr.atomic.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648)20; CHECK-NEXT: fence syncscope("wavefront") acquire21; CHECK-NEXT: [[ATOMIC_MONOTONIC:%.*]] = call float @llvm.amdgcn.raw.ptr.atomic.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)22; CHECK-NEXT: [[ATOMIC_ACQUIRE:%.*]] = call float @llvm.amdgcn.raw.ptr.atomic.buffer.load.f32(ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)23; CHECK-NEXT: fence acquire24; CHECK-NEXT: ret void25;26 %base = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)27 %p = getelementptr float, ptr addrspace(7) %base, i32 428 29 %scalar = load float, ptr addrspace(7) %p, align 430 %vec2 = load <2 x float>, ptr addrspace(7) %p, align 831 %vec4 = load <4 x float>, ptr addrspace(7) %p, align 1632 33 %nontemporal = load float, ptr addrspace(7) %p, !nontemporal !034 %invariant = load float, ptr addrspace(7) %p, !invariant.load !135 %nontemporal.invariant = load float, ptr addrspace(7) %p, !nontemporal !0, !invariant.load !136 37 %volatile = load volatile float, ptr addrspace(7) %p38 %volatile.nontemporal = load volatile float, ptr addrspace(7) %p, !nontemporal !039 40 %atomic = load atomic volatile float, ptr addrspace(7) %p syncscope("wavefront") seq_cst, align 441 %atomic.monotonic = load atomic float, ptr addrspace(7) %p syncscope("wavefront") monotonic, align 442 %atomic.acquire = load atomic float, ptr addrspace(7) %p acquire, align 443 44 ret void45}46 47define void @stores(ptr addrspace(8) %buf, float %f, <4 x float> %f4) {48; CHECK-LABEL: define void @stores49; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], float [[F:%.*]], <4 x float> [[F4:%.*]]) #[[ATTR0]] {50; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)51; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.v4f32(<4 x float> [[F4]], ptr addrspace(8) align 16 [[BUF]], i32 16, i32 0, i32 0)52; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0), !nontemporal [[META0]]53; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648)54; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648), !nontemporal [[META0]]55; CHECK-NEXT: fence syncscope("wavefront") release56; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648)57; CHECK-NEXT: fence syncscope("wavefront") acquire58; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)59; CHECK-NEXT: fence release60; CHECK-NEXT: call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)61; CHECK-NEXT: ret void62;63 %base = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)64 %p = getelementptr float, ptr addrspace(7) %base, i32 465 66 store float %f, ptr addrspace(7) %p, align 467 store <4 x float> %f4, ptr addrspace(7) %p, align 1668 69 store float %f, ptr addrspace(7) %p, !nontemporal !070 71 store volatile float %f, ptr addrspace(7) %p72 store volatile float %f, ptr addrspace(7) %p, !nontemporal !073 74 store atomic volatile float %f, ptr addrspace(7) %p syncscope("wavefront") seq_cst, align 475 store atomic float %f, ptr addrspace(7) %p syncscope("wavefront") monotonic, align 476 store atomic float %f, ptr addrspace(7) %p release, align 477 78 ret void79}80 81define void @atomicrmw(ptr addrspace(8) %buf, float %f, i32 %i) {82; CHECK-LABEL: define void @atomicrmw83; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], float [[F:%.*]], i32 [[I:%.*]]) #[[ATTR0]] {84; CHECK-NEXT: fence syncscope("wavefront") release85; CHECK-NEXT: [[XCHG:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.swap.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)86; CHECK-NEXT: fence syncscope("wavefront") acquire87; CHECK-NEXT: fence syncscope("wavefront") release88; CHECK-NEXT: [[ADD:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.add.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)89; CHECK-NEXT: fence syncscope("wavefront") acquire90; CHECK-NEXT: fence syncscope("wavefront") release91; CHECK-NEXT: [[SUB:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.sub.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)92; CHECK-NEXT: fence syncscope("wavefront") acquire93; CHECK-NEXT: fence syncscope("wavefront") release94; CHECK-NEXT: [[AND:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.and.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)95; CHECK-NEXT: fence syncscope("wavefront") acquire96; CHECK-NEXT: fence syncscope("wavefront") release97; CHECK-NEXT: [[OR:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.or.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)98; CHECK-NEXT: fence syncscope("wavefront") acquire99; CHECK-NEXT: fence syncscope("wavefront") release100; CHECK-NEXT: [[XOR:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.xor.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)101; CHECK-NEXT: fence syncscope("wavefront") acquire102; CHECK-NEXT: fence syncscope("wavefront") release103; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.smin.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)104; CHECK-NEXT: fence syncscope("wavefront") acquire105; CHECK-NEXT: fence syncscope("wavefront") release106; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.smax.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)107; CHECK-NEXT: fence syncscope("wavefront") acquire108; CHECK-NEXT: fence syncscope("wavefront") release109; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.umin.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)110; CHECK-NEXT: fence syncscope("wavefront") acquire111; CHECK-NEXT: fence syncscope("wavefront") release112; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.umax.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)113; CHECK-NEXT: fence syncscope("wavefront") acquire114; CHECK-NEXT: fence syncscope("wavefront") release115; CHECK-NEXT: [[FADD:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.atomic.fadd.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)116; CHECK-NEXT: fence syncscope("wavefront") acquire117; CHECK-NEXT: fence syncscope("wavefront") release118; CHECK-NEXT: [[FMAX:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.atomic.fmax.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)119; CHECK-NEXT: fence syncscope("wavefront") acquire120; CHECK-NEXT: fence syncscope("wavefront") release121; CHECK-NEXT: [[FMIN:%.*]] = call float @llvm.amdgcn.raw.ptr.buffer.atomic.fmin.f32(float [[F]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)122; CHECK-NEXT: fence syncscope("wavefront") acquire123; CHECK-NEXT: fence syncscope("wavefront") release124; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.add.i32(i32 [[I]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)125; CHECK-NEXT: fence syncscope("wavefront") acquire126; CHECK-NEXT: ret void127;128 %base = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)129 %p = getelementptr float, ptr addrspace(7) %base, i32 4130 131 ; Fence insertion is tested by loads and stores132 %xchg = atomicrmw xchg ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4133 %add = atomicrmw add ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4134 %sub = atomicrmw sub ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4135 %and = atomicrmw and ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4136 %or = atomicrmw or ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4137 %xor = atomicrmw xor ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4138 %min = atomicrmw min ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4139 %max = atomicrmw max ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4140 %umin = atomicrmw umin ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4141 %umax = atomicrmw umax ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4142 143 %fadd = atomicrmw fadd ptr addrspace(7) %p, float %f syncscope("wavefront") seq_cst, align 4144 %fmax = atomicrmw fmax ptr addrspace(7) %p, float %f syncscope("wavefront") seq_cst, align 4145 %fmin = atomicrmw fmin ptr addrspace(7) %p, float %f syncscope("wavefront") seq_cst, align 4146 147 ; Check a no-return atomic148 atomicrmw add ptr addrspace(7) %p, i32 %i syncscope("wavefront") seq_cst, align 4149 150 ret void151}152 153define {i32, i1} @cmpxchg(ptr addrspace(8) %buf, i32 %wanted, i32 %new) {154; CHECK-LABEL: define { i32, i1 } @cmpxchg155; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[WANTED:%.*]], i32 [[NEW:%.*]]) #[[ATTR0]] {156; CHECK-NEXT: fence syncscope("wavefront") release157; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.cmpswap.i32(i32 [[NEW]], i32 [[WANTED]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 -2147483648)158; CHECK-NEXT: fence syncscope("wavefront") acquire159; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } poison, i32 [[RET]], 0160; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[RET]], [[WANTED]]161; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 [[TMP2]], 1162; CHECK-NEXT: ret { i32, i1 } [[TMP3]]163;164 %base = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)165 %p = getelementptr i32, ptr addrspace(7) %base, i32 4166 167 %ret = cmpxchg volatile ptr addrspace(7) %p, i32 %wanted, i32 %new syncscope("wavefront") acq_rel monotonic, align 4168 ret {i32, i1} %ret169}170 171define {i32, i1} @cmpxchg_weak(ptr addrspace(8) %buf, i32 %wanted, i32 %new) {172; CHECK-LABEL: define { i32, i1 } @cmpxchg_weak173; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]], i32 [[WANTED:%.*]], i32 [[NEW:%.*]]) #[[ATTR0]] {174; CHECK-NEXT: fence syncscope("wavefront") release175; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.atomic.cmpswap.i32(i32 [[NEW]], i32 [[WANTED]], ptr addrspace(8) align 4 [[BUF]], i32 16, i32 0, i32 0)176; CHECK-NEXT: fence syncscope("wavefront") acquire177; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } poison, i32 [[RET]], 0178; CHECK-NEXT: ret { i32, i1 } [[TMP1]]179;180 %base = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)181 %p = getelementptr i32, ptr addrspace(7) %base, i32 4182 183 %ret = cmpxchg weak ptr addrspace(7) %p, i32 %wanted, i32 %new syncscope("wavefront") acq_rel monotonic, align 4184 ret {i32, i1} %ret185}186 187!0 = ! { i32 1 }188!1 = ! { }189