Index: llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.f32-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.f32-no-rtn.ll @@ -0,0 +1,142 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI100_GFX11 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI100_GFX11 %s + +define amdgpu_ps void @buffer_atomic_fadd_f32_offset_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_offset_no_rtn + ; MI100_GFX11: bb.1 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_OFFSET [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offset_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_OFFSET [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f32_offen_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_offen_no_rtn + ; MI100_GFX11: bb.1 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_OFFEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_OFFEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f32_idxen_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_idxen_no_rtn + ; MI100_GFX11: bb.1 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_IDXEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_idxen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_IDXEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f32_bothen_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_bothen_no_rtn + ; MI100_GFX11: bb.1 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100_GFX11-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_BOTHEN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_bothen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_BOTHEN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret void +} + +declare float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32 immarg) +declare float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.f32-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.f32-rtn.ll @@ -0,0 +1,149 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=GFX11 %s + +define amdgpu_ps float @buffer_atomic_fadd_f32_offset_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offset_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFSET_RTN [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_offset_rtn + ; GFX11: bb.1 (%ir-block.0): + ; GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFSET_RTN [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret float %ret +} + +define amdgpu_ps float @buffer_atomic_fadd_f32_offen_rtn(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFEN_RTN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_offen_rtn + ; GFX11: bb.1 (%ir-block.0): + ; GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; GFX11-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFEN_RTN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret float %ret +} + +define amdgpu_ps float @buffer_atomic_fadd_f32_idxen_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_idxen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_IDXEN_RTN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_idxen_rtn + ; GFX11: bb.1 (%ir-block.0): + ; GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; GFX11-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_IDXEN_RTN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret float %ret +} + +define amdgpu_ps float @buffer_atomic_fadd_f32_bothen_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_bothen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_bothen_rtn + ; GFX11: bb.1 (%ir-block.0): + ; GFX11-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; GFX11-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; GFX11-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; GFX11-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 0) + ret float %ret +} + +declare float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32 immarg) +declare float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.f64.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.f64.ll @@ -0,0 +1,200 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @buffer_atomic_fadd_f64_offset_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offset_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_OFFSET [[REG_SEQUENCE]], [[REG_SEQUENCE1]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f64_offen_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_OFFEN [[REG_SEQUENCE]], [[COPY6]], [[REG_SEQUENCE1]], [[COPY7]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f64_idxen_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_idxen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_IDXEN [[REG_SEQUENCE]], [[COPY6]], [[REG_SEQUENCE1]], [[COPY7]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f64_bothen_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_bothen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[REG_SEQUENCE2:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY7]], %subreg.sub1 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_BOTHEN [[REG_SEQUENCE]], [[REG_SEQUENCE2]], [[REG_SEQUENCE1]], [[COPY8]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret void +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_offset_rtn(double %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offset_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_OFFSET_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_OFFSET_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE1]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFSET_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFSET_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY8]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret double %ret +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_offen_rtn(double %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_OFFEN_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_OFFEN_RTN [[REG_SEQUENCE]], [[COPY6]], [[REG_SEQUENCE1]], [[COPY7]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFEN_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFEN_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY8]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY9]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret double %ret +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_idxen_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_idxen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_IDXEN_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_IDXEN_RTN [[REG_SEQUENCE]], [[COPY6]], [[REG_SEQUENCE1]], [[COPY7]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_IDXEN_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_IDXEN_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY8]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY9]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret double %ret +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_bothen_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_bothen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY5]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[REG_SEQUENCE2:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY7]], %subreg.sub1 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE2]], [[REG_SEQUENCE1]], [[COPY8]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY10:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY9]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY10]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 0) + ret double %ret +} + +declare double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double, <4 x i32>, i32, i32, i32 immarg) +declare double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.v2f16-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.v2f16-no-rtn.ll @@ -0,0 +1,141 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI100 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_offset_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_offset_no_rtn + ; MI100: bb.1 (%ir-block.0): + ; MI100-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFSET [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 4095, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offset_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFSET [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 4095, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 4095, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_offen_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_offen_no_rtn + ; MI100: bb.1 (%ir-block.0): + ; MI100-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_idxen_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_idxen_no_rtn + ; MI100: bb.1 (%ir-block.0): + ; MI100-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_IDXEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_idxen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_IDXEN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_bothen_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_bothen_no_rtn + ; MI100: bb.1 (%ir-block.0): + ; MI100-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI100-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_BOTHEN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 2, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_bothen_no_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_BOTHEN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 2, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret void +} + +declare <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32 immarg) +declare <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.v2f16-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/buffer-atomic-fadd.v2f16-rtn.ll @@ -0,0 +1,87 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_offset_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offset_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_OFFSET_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_OFFSET_RTN [[COPY]], [[REG_SEQUENCE]], [[COPY5]], 0, 1, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_OFFSET_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_offen_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_OFFEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_OFFEN_RTN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_OFFEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_idxen_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_idxen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_IDXEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_IDXEN_RTN [[COPY]], [[COPY5]], [[REG_SEQUENCE]], [[COPY6]], 0, 1, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_IDXEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_bothen_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_bothen_rtn + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4, $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY4]], %subreg.sub3 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:sreg_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_BOTHEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_BOTHEN_RTN [[COPY]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], [[COPY7]], 0, 3, implicit $exec :: (volatile dereferenceable load store (<2 x s16>), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_BOTHEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret <2 x half> %ret +} + +declare <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32 immarg) +declare <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/flat-atomic-fadd.f32.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/flat-atomic-fadd.f32.ll @@ -0,0 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI300 %s +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=GFX11 %s + +; MI300: LLVM ERROR: unable to legalize instruction: %{{[0-9]+}}:_(s32) = G_ATOMICRMW_FADD +; GFX11: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.flat.atomic.fadd) + +define amdgpu_ps void @flat_atomic_fadd_f32_no_rtn_intrinsic(float* %ptr, float %data) { + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float* %ptr, float %data) + ret void +} + +define amdgpu_ps float @flat_atomic_fadd_f32_rtn_intrinsic(float* %ptr, float %data) { + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float* %ptr, float %data) + ret float %ret +} + +define amdgpu_ps void @flat_atomic_fadd_f32_no_rtn_atomicrmw(float* %ptr, float %data) #0 { + %ret = atomicrmw fadd float* %ptr, float %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps float @flat_atomic_fadd_f32_rtn_atomicrmw(float* %ptr, float %data) #0 { + %ret = atomicrmw fadd float* %ptr, float %data syncscope("wavefront") monotonic + ret float %ret +} + +declare float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float*, float) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/GlobalISel/flat-atomic-fadd.f64.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/flat-atomic-fadd.f64.ll @@ -0,0 +1,87 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @flat_atomic_fadd_f64_no_rtn_intrinsic(double* %ptr, double %data) { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_no_rtn_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: FLAT_ATOMIC_ADD_F64 [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double* %ptr, double %data) + ret void +} + +define amdgpu_ps double @flat_atomic_fadd_f64_rtn_intrinsic(double* %ptr, double %data) { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_rtn_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[FLAT_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = FLAT_ATOMIC_ADD_F64_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @flat_atomic_fadd_f64_no_rtn_atomicrmw(double* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_no_rtn_atomicrmw + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: FLAT_ATOMIC_ADD_F64 [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 0, implicit $exec, implicit $flat_scr :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd double* %ptr, double %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps double @flat_atomic_fadd_f64_rtn_atomicrmw(double* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_rtn_atomicrmw + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[FLAT_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = FLAT_ATOMIC_ADD_F64_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 1, implicit $exec, implicit $flat_scr :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = atomicrmw fadd double* %ptr, double %data syncscope("wavefront") monotonic + ret double %ret +} + +declare double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double*, double) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/GlobalISel/flat-atomic-fadd.v2f16.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/flat-atomic-fadd.v2f16.ll @@ -0,0 +1,35 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI300 %s + +define amdgpu_ps void @flat_atomic_fadd_v2f16_no_rtn_intrinsic(<2 x half>* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: flat_atomic_fadd_v2f16_no_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: FLAT_ATOMIC_PK_ADD_F16 [[REG_SEQUENCE]], [[COPY2]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half>* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps <2 x half> @flat_atomic_fadd_v2f16_rtn_intrinsic(<2 x half>* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: flat_atomic_fadd_v2f16_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[FLAT_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_PK_ADD_F16_RTN [[REG_SEQUENCE]], [[COPY2]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_PK_ADD_F16_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half>* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +declare <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half>*, <2 x half>) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.f32-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.f32-no-rtn.ll @@ -0,0 +1,105 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI100_MI200_GFX11 %s +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI100_MI200_GFX11 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI300 %s +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI100_MI200_GFX11 %s + +; MI100_MI200_GFX11: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.flat.atomic.fadd) + +define amdgpu_ps void @global_atomic_fadd_f32_no_rtn_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_no_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: GLOBAL_ATOMIC_ADD_F32 [[REG_SEQUENCE]], [[COPY2]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_saddr_no_rtn_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI300-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR [[V_MOV_B32_e32_]], [[COPY2]], [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_no_rtn_flat_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_no_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: FLAT_ATOMIC_ADD_F32 [[REG_SEQUENCE]], [[COPY2]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_saddr_no_rtn_flat_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: FLAT_ATOMIC_ADD_F32 [[COPY3]], [[COPY2]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_no_rtn_atomicrmw(float addrspace(1)* %ptr, float %data) #0 { + ; MI300-LABEL: name: global_atomic_fadd_f32_no_rtn_atomicrmw + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: GLOBAL_ATOMIC_ADD_F32 [[REG_SEQUENCE]], [[COPY2]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_saddr_no_rtn_atomicrmw(float addrspace(1)* inreg %ptr, float %data) #0 { + ; MI300-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_atomicrmw + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI300-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR [[V_MOV_B32_e32_]], [[COPY2]], [[REG_SEQUENCE]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret void +} + +declare float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) +declare float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.f32-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.f32-rtn.ll @@ -0,0 +1,111 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI200 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI300 %s +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=GFX11 %s + +; MI200: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.flat.atomic.fadd) +; GFX11: error: {{.*}} return versions of fp atomics not supported + +define amdgpu_ps float @global_atomic_fadd_f32_rtn_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_RTN [[REG_SEQUENCE]], [[COPY2]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_saddr_rtn_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_saddr_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_SADDR_RTN [[V_MOV_B32_e32_]], [[COPY2]], [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_rtn_flat_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[FLAT_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_ADD_F32_RTN [[REG_SEQUENCE]], [[COPY2]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_ADD_F32_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_saddr_rtn_flat_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI300-LABEL: name: global_atomic_fadd_f32_saddr_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: [[FLAT_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_ADD_F32_RTN [[COPY3]], [[COPY2]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_ADD_F32_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_rtn_atomicrmw(float addrspace(1)* %ptr, float %data) #0 { + ; MI300-LABEL: name: global_atomic_fadd_f32_rtn_atomicrmw + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_RTN [[REG_SEQUENCE]], [[COPY2]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_saddr_rtn_atomicrmw(float addrspace(1)* inreg %ptr, float %data) #0 { + ; MI300-LABEL: name: global_atomic_fadd_f32_saddr_rtn_atomicrmw + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_SADDR_RTN [[V_MOV_B32_e32_]], [[COPY2]], [[REG_SEQUENCE]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret float %ret +} + +declare float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) +declare float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.f64.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.f64.ll @@ -0,0 +1,254 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @global_atomic_fadd_f64_no_rtn_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_no_rtn_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64 [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_rtn_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_rtn_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_saddr_no_rtn_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_no_rtn_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64_SADDR [[V_MOV_B32_e32_]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_saddr_rtn_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_rtn_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_SADDR_RTN [[V_MOV_B32_e32_]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_no_rtn_flat_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_no_rtn_flat_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: FLAT_ATOMIC_ADD_F64 [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_rtn_flat_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_rtn_flat_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[FLAT_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = FLAT_ATOMIC_ADD_F64_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_saddr_no_rtn_flat_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_no_rtn_flat_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: FLAT_ATOMIC_ADD_F64 [[COPY4]], [[REG_SEQUENCE1]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_saddr_rtn_flat_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_rtn_flat_intrinsic + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[FLAT_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = FLAT_ATOMIC_ADD_F64_RTN [[COPY4]], [[REG_SEQUENCE1]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_no_rtn_atomicrmw(double addrspace(1)* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_no_rtn_atomicrmw + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64 [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_rtn_atomicrmw(double addrspace(1)* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_rtn_atomicrmw + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_RTN [[REG_SEQUENCE]], [[REG_SEQUENCE1]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_saddr_no_rtn_atomicrmw(double addrspace(1)* inreg %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_no_rtn_atomicrmw + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64_SADDR [[V_MOV_B32_e32_]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_saddr_rtn_atomicrmw(double addrspace(1)* inreg %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_rtn_atomicrmw + ; MI200_MI300: bb.1 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY3]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_SADDR_RTN [[V_MOV_B32_e32_]], [[REG_SEQUENCE1]], [[REG_SEQUENCE]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub1 + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec + ; MI200_MI300-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]] + ; MI200_MI300-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec + ; MI200_MI300-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret double %ret +} + +declare double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)*, double) +declare double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)*, double) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.v2f16-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.v2f16-no-rtn.ll @@ -0,0 +1,71 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI100_MI200 %s +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI100_MI200 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI300 %s + +; MI100_MI200: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr(<2 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.flat.atomic.fadd) + +define amdgpu_ps void @global_atomic_fadd_v2f16_no_rtn_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_no_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: GLOBAL_ATOMIC_PK_ADD_F16 [[REG_SEQUENCE]], [[COPY2]], 0, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_v2f16_saddr_no_rtn_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_no_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI300-NEXT: GLOBAL_ATOMIC_PK_ADD_F16_SADDR [[V_MOV_B32_e32_]], [[COPY2]], [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_v2f16_no_rtn_flat_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_no_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: FLAT_ATOMIC_PK_ADD_F16 [[REG_SEQUENCE]], [[COPY2]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_v2f16_saddr_no_rtn_flat_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_no_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: FLAT_ATOMIC_PK_ADD_F16 [[COPY3]], [[COPY2]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +declare <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) +declare <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) Index: llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.v2f16-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/global-atomic-fadd.v2f16-rtn.ll @@ -0,0 +1,74 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: not --crash llc -global-isel -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=instruction-select < %s 2>&1 | FileCheck -check-prefix=MI200 %s +; RUN: llc -global-isel -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=instruction-select < %s | FileCheck -check-prefix=MI300 %s + +; MI200: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(<2 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.amdgcn.flat.atomic.fadd) + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_rtn_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[GLOBAL_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_PK_ADD_F16_RTN [[REG_SEQUENCE]], [[COPY2]], 0, 1, implicit $exec :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_PK_ADD_F16_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_saddr_rtn_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_rtn_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI300-NEXT: [[GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN [[V_MOV_B32_e32_]], [[COPY2]], [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_rtn_flat_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[FLAT_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_PK_ADD_F16_RTN [[REG_SEQUENCE]], [[COPY2]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_PK_ADD_F16_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_saddr_rtn_flat_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_rtn_flat_intrinsic + ; MI300: bb.1 (%ir-block.0): + ; MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: [[FLAT_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_PK_ADD_F16_RTN [[COPY3]], [[COPY2]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (<2 x s16>) on %ir.ptr, addrspace 1) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_PK_ADD_F16_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG implicit $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +declare <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) +declare <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) Index: llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll @@ -0,0 +1,142 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI100_GFX11 %s +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI100_GFX11 %s + +define amdgpu_ps void @buffer_atomic_fadd_f32_offset_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_offset_no_rtn + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_OFFSET [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offset_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_OFFSET [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f32_offen_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_offen_no_rtn + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_OFFEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_OFFEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f32_idxen_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_idxen_no_rtn + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_IDXEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_idxen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_IDXEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f32_bothen_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI100_GFX11-LABEL: name: buffer_atomic_fadd_f32_bothen_no_rtn + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100_GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100_GFX11-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: BUFFER_ATOMIC_ADD_F32_BOTHEN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_bothen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F32_BOTHEN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret void +} + +declare float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32 immarg) +declare float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll @@ -0,0 +1,149 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s + +define amdgpu_ps float @buffer_atomic_fadd_f32_offset_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offset_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFSET_RTN [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_offset_rtn + ; GFX11: bb.0 (%ir-block.0): + ; GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFSET_RTN [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFSET_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret float %ret +} + +define amdgpu_ps float @buffer_atomic_fadd_f32_offen_rtn(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_offen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFEN_RTN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_offen_rtn + ; GFX11: bb.0 (%ir-block.0): + ; GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_OFFEN_RTN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_OFFEN_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret float %ret +} + +define amdgpu_ps float @buffer_atomic_fadd_f32_idxen_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_idxen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_IDXEN_RTN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_idxen_rtn + ; GFX11: bb.0 (%ir-block.0): + ; GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_IDXEN_RTN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_IDXEN_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret float %ret +} + +define amdgpu_ps float @buffer_atomic_fadd_f32_bothen_rtn(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f32_bothen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + ; GFX11-LABEL: name: buffer_atomic_fadd_f32_bothen_rtn + ; GFX11: bb.0 (%ir-block.0): + ; GFX11-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; GFX11-NEXT: {{ $}} + ; GFX11-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; GFX11-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; GFX11-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; GFX11-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; GFX11-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; GFX11-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; GFX11-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; GFX11-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; GFX11-NEXT: [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; GFX11-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_ADD_F32_BOTHEN_RTN]] + ; GFX11-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 0) + ret float %ret +} + +declare float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32 immarg) +declare float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll @@ -0,0 +1,200 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @buffer_atomic_fadd_f64_offset_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offset_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_OFFSET killed [[COPY7]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f64_offen_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY7]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_OFFEN killed [[COPY8]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f64_idxen_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_idxen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY7]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_IDXEN killed [[COPY8]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_f64_bothen_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_bothen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr2, $vgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY8]], %subreg.sub0, [[COPY7]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE2:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: BUFFER_ATOMIC_ADD_F64_BOTHEN killed [[COPY9]], killed [[REG_SEQUENCE2]], killed [[REG_SEQUENCE]], [[COPY]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret void +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_offset_rtn(double %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offset_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_OFFSET_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_OFFSET_RTN [[COPY7]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFSET_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFSET_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY8]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY9]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret double %ret +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_offen_rtn(double %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_offen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY7]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_OFFEN_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_OFFEN_RTN [[COPY8]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFEN_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY10:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_OFFEN_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY9]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY10]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret double %ret +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_idxen_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_idxen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY7]], %subreg.sub0, [[COPY6]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_IDXEN_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_IDXEN_RTN [[COPY8]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_IDXEN_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY10:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_IDXEN_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY9]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY10]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret double %ret +} + +define amdgpu_ps double @buffer_atomic_fadd_f64_bothen_rtn(double %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_f64_bothen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr2, $vgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY8]], %subreg.sub0, [[COPY7]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE2:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY9:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN:%[0-9]+]]:vreg_64_align2 = BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN [[COPY9]], killed [[REG_SEQUENCE2]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64), align 1, addrspace 4) + ; MI200_MI300-NEXT: [[COPY10:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY11:%[0-9]+]]:vgpr_32 = COPY [[BUFFER_ATOMIC_ADD_F64_BOTHEN_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY10]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY11]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 0) + ret double %ret +} + +declare double @llvm.amdgcn.raw.buffer.atomic.fadd.f64(double, <4 x i32>, i32, i32, i32 immarg) +declare double @llvm.amdgcn.struct.buffer.atomic.fadd.f64(double, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll @@ -0,0 +1,141 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI100 %s +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_offset_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_offset_no_rtn + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFSET [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 4095, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offset_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFSET [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 4095, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 4095, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_offen_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_offen_no_rtn + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_OFFEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_idxen_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_idxen_no_rtn + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_IDXEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_idxen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_IDXEN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret void +} + +define amdgpu_ps void @buffer_atomic_fadd_v2f16_bothen_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI100-LABEL: name: buffer_atomic_fadd_v2f16_bothen_no_rtn + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI100-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI100-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI100-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100-NEXT: BUFFER_ATOMIC_PK_ADD_F16_BOTHEN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_bothen_no_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: BUFFER_ATOMIC_PK_ADD_F16_BOTHEN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 2, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret void +} + +declare <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32 immarg) +declare <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll @@ -0,0 +1,87 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_offset_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offset_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_OFFSET_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_OFFSET_RTN [[COPY5]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_OFFSET_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 0, i32 %soffset, i32 0) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_offen_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_offen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_OFFEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_OFFEN_RTN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_OFFEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 0) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_idxen_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_idxen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY5]], %subreg.sub0, [[COPY4]], %subreg.sub1, [[COPY3]], %subreg.sub2, [[COPY2]], %subreg.sub3 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_IDXEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_IDXEN_RTN [[COPY6]], [[COPY1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_IDXEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 0) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_bothen_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { + ; MI200_MI300-LABEL: name: buffer_atomic_fadd_v2f16_bothen_rtn + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $sgpr0, $sgpr1, $sgpr2, $sgpr3, $vgpr1, $vgpr2, $sgpr4 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr3 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr2 + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY6]], %subreg.sub0, [[COPY5]], %subreg.sub1, [[COPY4]], %subreg.sub2, [[COPY3]], %subreg.sub3 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:vreg_64_align2 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[BUFFER_ATOMIC_PK_ADD_F16_BOTHEN_RTN:%[0-9]+]]:vgpr_32 = BUFFER_ATOMIC_PK_ADD_F16_BOTHEN_RTN [[COPY7]], killed [[REG_SEQUENCE1]], killed [[REG_SEQUENCE]], [[COPY]], 0, 3, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 4) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[BUFFER_ATOMIC_PK_ADD_F16_BOTHEN_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half> %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) + ret <2 x half> %ret +} + +declare <2 x half> @llvm.amdgcn.raw.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32 immarg) +declare <2 x half> @llvm.amdgcn.struct.buffer.atomic.fadd.v2f16(<2 x half>, <4 x i32>, i32, i32, i32, i32 immarg) Index: llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll @@ -0,0 +1,75 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI300 %s +; RUN: not --crash llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s 2>&1 | FileCheck -check-prefix=GFX11 %s + +; GFX11: LLVM ERROR: Cannot select: {{.+}}: f32,ch = AtomicLoadFAdd + +define amdgpu_ps void @flat_atomic_fadd_f32_no_rtn_intrinsic(float* %ptr, float %data) { + ; MI300-LABEL: name: flat_atomic_fadd_f32_no_rtn_intrinsic + ; MI300: bb.0 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: FLAT_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float* %ptr, float %data) + ret void +} + +define amdgpu_ps float @flat_atomic_fadd_f32_rtn_intrinsic(float* %ptr, float %data) { + ; MI300-LABEL: name: flat_atomic_fadd_f32_rtn_intrinsic + ; MI300: bb.0 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: [[FLAT_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_ADD_F32_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_ADD_F32_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float* %ptr, float %data) + ret float %ret +} + +define amdgpu_ps void @flat_atomic_fadd_f32_no_rtn_atomicrmw(float* %ptr, float %data) #0 { + ; MI300-LABEL: name: flat_atomic_fadd_f32_no_rtn_atomicrmw + ; MI300: bb.0 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: FLAT_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec, implicit $flat_scr :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr) + ; MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd float* %ptr, float %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps float @flat_atomic_fadd_f32_rtn_atomicrmw(float* %ptr, float %data) #0 { + ; MI300-LABEL: name: flat_atomic_fadd_f32_rtn_atomicrmw + ; MI300: bb.0 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: [[FLAT_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_ADD_F32_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec, implicit $flat_scr :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_ADD_F32_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = atomicrmw fadd float* %ptr, float %data syncscope("wavefront") monotonic + ret float %ret +} + +declare float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float*, float) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll @@ -0,0 +1,91 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @flat_atomic_fadd_f64_no_rtn_intrinsic(double* %ptr, double %data) { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: FLAT_ATOMIC_ADD_F64 killed [[COPY4]], killed [[COPY5]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double* %ptr, double %data) + ret void +} + +define amdgpu_ps double @flat_atomic_fadd_f64_rtn_intrinsic(double* %ptr, double %data) { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[FLAT_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = FLAT_ATOMIC_ADD_F64_RTN killed [[COPY4]], killed [[COPY5]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s64) on %ir.ptr) + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY6]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY7]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @flat_atomic_fadd_f64_no_rtn_atomicrmw(double* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_no_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: FLAT_ATOMIC_ADD_F64 killed [[COPY4]], killed [[COPY5]], 0, 0, implicit $exec, implicit $flat_scr :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd double* %ptr, double %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps double @flat_atomic_fadd_f64_rtn_atomicrmw(double* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: flat_atomic_fadd_f64_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[FLAT_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = FLAT_ATOMIC_ADD_F64_RTN killed [[COPY4]], killed [[COPY5]], 0, 1, implicit $exec, implicit $flat_scr :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr) + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[FLAT_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY6]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY7]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = atomicrmw fadd double* %ptr, double %data syncscope("wavefront") monotonic + ret double %ret +} + +declare double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double*, double) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.v2f16.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.v2f16.ll @@ -0,0 +1,37 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI300 %s + +define amdgpu_ps void @flat_atomic_fadd_v2f16_no_rtn_intrinsic(<2 x half>* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: flat_atomic_fadd_v2f16_no_rtn_intrinsic + ; MI300: bb.0 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: FLAT_ATOMIC_PK_ADD_F16 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr) + ; MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half>* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps <2 x half> @flat_atomic_fadd_v2f16_rtn_intrinsic(<2 x half>* %ptr, <2 x half> %data) { + ; MI300-LABEL: name: flat_atomic_fadd_v2f16_rtn_intrinsic + ; MI300: bb.0 (%ir-block.0): + ; MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI300-NEXT: {{ $}} + ; MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI300-NEXT: [[FLAT_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = FLAT_ATOMIC_PK_ADD_F16_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec, implicit $flat_scr :: (volatile dereferenceable load store (s32) on %ir.ptr) + ; MI300-NEXT: $vgpr0 = COPY [[FLAT_ATOMIC_PK_ADD_F16_RTN]] + ; MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half>* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +declare <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half>*, <2 x half>) Index: llvm/test/CodeGen/AMDGPU/global-atomic-fadd.f32-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/global-atomic-fadd.f32-no-rtn.ll @@ -0,0 +1,172 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI100_GFX11 %s +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI100_GFX11 %s + +define amdgpu_ps void @global_atomic_fadd_f32_no_rtn_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI100_GFX11-LABEL: name: global_atomic_fadd_f32_no_rtn_intrinsic + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] + ; MI100_GFX11-NEXT: GLOBAL_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_saddr_no_rtn_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI100_GFX11-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_intrinsic + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI100_GFX11-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_no_rtn_flat_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI100_GFX11-LABEL: name: global_atomic_fadd_f32_no_rtn_flat_intrinsic + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] + ; MI100_GFX11-NEXT: GLOBAL_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_no_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_saddr_no_rtn_flat_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI100_GFX11-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_flat_intrinsic + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI100_GFX11-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_no_rtn_atomicrmw(float addrspace(1)* %ptr, float %data) #0 { + ; MI100_GFX11-LABEL: name: global_atomic_fadd_f32_no_rtn_atomicrmw + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] + ; MI100_GFX11-NEXT: GLOBAL_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_no_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F32 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps void @global_atomic_fadd_f32_saddr_no_rtn_atomicrmw(float addrspace(1)* inreg %ptr, float %data) #0 { + ; MI100_GFX11-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_atomicrmw + ; MI100_GFX11: bb.0 (%ir-block.0): + ; MI100_GFX11-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI100_GFX11-NEXT: {{ $}} + ; MI100_GFX11-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100_GFX11-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100_GFX11-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100_GFX11-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100_GFX11-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI100_GFX11-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI100_GFX11-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_saddr_no_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F32_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret void +} + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } + +declare float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) +declare float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) Index: llvm/test/CodeGen/AMDGPU/global-atomic-fadd.f32-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/global-atomic-fadd.f32-rtn.ll @@ -0,0 +1,113 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: not --crash llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s 2>&1 | FileCheck -check-prefix=GFX11 %s + +; GFX11: error: {{.*}} return versions of fp atomics not supported + +define amdgpu_ps float @global_atomic_fadd_f32_rtn_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_saddr_rtn_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_saddr_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_SADDR_RTN killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_rtn_flat_intrinsic(float addrspace(1)* %ptr, float %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_saddr_rtn_flat_intrinsic(float addrspace(1)* inreg %ptr, float %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_saddr_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_SADDR_RTN killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)* inreg %ptr, float %data) + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_rtn_atomicrmw(float addrspace(1)* %ptr, float %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret float %ret +} + +define amdgpu_ps float @global_atomic_fadd_f32_saddr_rtn_atomicrmw(float addrspace(1)* inreg %ptr, float %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f32_saddr_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_ADD_F32_SADDR_RTN killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_ADD_F32_SADDR_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = atomicrmw fadd float addrspace(1)* %ptr, float %data syncscope("wavefront") monotonic + ret float %ret +} + +declare float @llvm.amdgcn.global.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) +declare float @llvm.amdgcn.flat.atomic.fadd.f32.p1f32.f32(float addrspace(1)*, float) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/global-atomic-fadd.f64.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/global-atomic-fadd.f64.ll @@ -0,0 +1,260 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @global_atomic_fadd_f64_no_rtn_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64 killed [[COPY4]], killed [[COPY5]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_rtn_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_RTN killed [[COPY4]], killed [[COPY5]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY6]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY7]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_saddr_no_rtn_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64_SADDR killed [[V_MOV_B32_e32_]], killed [[COPY4]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_saddr_rtn_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_SADDR_RTN killed [[V_MOV_B32_e32_]], killed [[COPY4]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY5]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY6]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_no_rtn_flat_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_no_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64 killed [[COPY4]], killed [[COPY5]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_rtn_flat_intrinsic(double addrspace(1)* %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_RTN killed [[COPY4]], killed [[COPY5]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY6]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY7]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_saddr_no_rtn_flat_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_no_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64_SADDR killed [[V_MOV_B32_e32_]], killed [[COPY4]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_saddr_rtn_flat_intrinsic(double addrspace(1)* inreg %ptr, double %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_SADDR_RTN killed [[V_MOV_B32_e32_]], killed [[COPY4]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY5]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY6]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = call double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)* %ptr, double %data) + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_no_rtn_atomicrmw(double addrspace(1)* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_no_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64 killed [[COPY4]], killed [[COPY5]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_rtn_atomicrmw(double addrspace(1)* %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr3 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_RTN killed [[COPY4]], killed [[COPY5]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY6]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY7]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret double %ret +} + +define amdgpu_ps void @global_atomic_fadd_f64_saddr_no_rtn_atomicrmw(double addrspace(1)* inreg %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_no_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_ADD_F64_SADDR killed [[V_MOV_B32_e32_]], killed [[COPY4]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret void +} + +define amdgpu_ps double @global_atomic_fadd_f64_saddr_rtn_atomicrmw(double addrspace(1)* inreg %ptr, double %data) #0 { + ; MI200_MI300-LABEL: name: global_atomic_fadd_f64_saddr_rtn_atomicrmw + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr1 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1 + ; MI200_MI300-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[COPY4:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE1]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN:%[0-9]+]]:vreg_64_align2 = GLOBAL_ATOMIC_ADD_F64_SADDR_RTN killed [[V_MOV_B32_e32_]], killed [[COPY4]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (load store syncscope("wavefront") monotonic (s64) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub0 + ; MI200_MI300-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[GLOBAL_ATOMIC_ADD_F64_SADDR_RTN]].sub1 + ; MI200_MI300-NEXT: $sgpr0 = COPY [[COPY5]] + ; MI200_MI300-NEXT: $sgpr1 = COPY [[COPY6]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1 + %ret = atomicrmw fadd double addrspace(1)* %ptr, double %data syncscope("wavefront") monotonic + ret double %ret +} + +declare double @llvm.amdgcn.global.atomic.fadd.f64.p1f64.f64(double addrspace(1)*, double) +declare double @llvm.amdgcn.flat.atomic.fadd.f64.p1f64.f64(double addrspace(1)*, double) + +attributes #0 = {"amdgpu-unsafe-fp-atomics"="true" } Index: llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll @@ -0,0 +1,115 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI100 %s +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps void @global_atomic_fadd_v2f16_no_rtn_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI100-LABEL: name: global_atomic_fadd_v2f16_no_rtn_intrinsic + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] + ; MI100-NEXT: GLOBAL_ATOMIC_PK_ADD_F16 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_PK_ADD_F16 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_v2f16_saddr_no_rtn_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI100-LABEL: name: global_atomic_fadd_v2f16_saddr_no_rtn_intrinsic + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI100-NEXT: GLOBAL_ATOMIC_PK_ADD_F16_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_no_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_PK_ADD_F16_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_v2f16_no_rtn_flat_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI100-LABEL: name: global_atomic_fadd_v2f16_no_rtn_flat_intrinsic + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100-NEXT: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] + ; MI100-NEXT: GLOBAL_ATOMIC_PK_ADD_F16 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_no_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_PK_ADD_F16 killed [[COPY3]], [[COPY]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +define amdgpu_ps void @global_atomic_fadd_v2f16_saddr_no_rtn_flat_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI100-LABEL: name: global_atomic_fadd_v2f16_saddr_no_rtn_flat_intrinsic + ; MI100: bb.0 (%ir-block.0): + ; MI100-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI100-NEXT: {{ $}} + ; MI100-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI100-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI100-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI100-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI100-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI100-NEXT: GLOBAL_ATOMIC_PK_ADD_F16_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI100-NEXT: S_ENDPGM 0 + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_no_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: GLOBAL_ATOMIC_PK_ADD_F16_SADDR killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 0, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: S_ENDPGM 0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret void +} + +declare <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) +declare <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) Index: llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll @@ -0,0 +1,74 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -march=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s +; RUN: llc -march=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=MI200_MI300 %s + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_rtn_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_PK_ADD_F16_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_PK_ADD_F16_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_saddr_rtn_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_rtn_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_rtn_flat_intrinsic(<2 x half> addrspace(1)* %ptr, <2 x half> %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[COPY3:%[0-9]+]]:vreg_64_align2 = COPY [[REG_SEQUENCE]] + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_PK_ADD_F16_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_PK_ADD_F16_RTN killed [[COPY3]], [[COPY]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_PK_ADD_F16_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_saddr_rtn_flat_intrinsic(<2 x half> addrspace(1)* inreg %ptr, <2 x half> %data) { + ; MI200_MI300-LABEL: name: global_atomic_fadd_v2f16_saddr_rtn_flat_intrinsic + ; MI200_MI300: bb.0 (%ir-block.0): + ; MI200_MI300-NEXT: liveins: $sgpr0, $sgpr1, $vgpr0 + ; MI200_MI300-NEXT: {{ $}} + ; MI200_MI300-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; MI200_MI300-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1 + ; MI200_MI300-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0 + ; MI200_MI300-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1 + ; MI200_MI300-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; MI200_MI300-NEXT: [[GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN:%[0-9]+]]:vgpr_32 = GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN killed [[V_MOV_B32_e32_]], [[COPY]], killed [[REG_SEQUENCE]], 0, 1, implicit $exec :: (volatile dereferenceable load store (s32) on %ir.ptr, addrspace 1) + ; MI200_MI300-NEXT: $vgpr0 = COPY [[GLOBAL_ATOMIC_PK_ADD_F16_SADDR_RTN]] + ; MI200_MI300-NEXT: SI_RETURN_TO_EPILOG $vgpr0 + %ret = call <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)* %ptr, <2 x half> %data) + ret <2 x half> %ret +} + +declare <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) +declare <2 x half> @llvm.amdgcn.flat.atomic.fadd.v2f16.p1v2f16.v2f16(<2 x half> addrspace(1)*, <2 x half>) Index: llvm/test/CodeGen/AMDGPU/llvm.amdgcn.atomic.fadd.rtn_no-rtn.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/llvm.amdgcn.atomic.fadd.rtn_no-rtn.ll +++ /dev/null @@ -1,99 +0,0 @@ -; RUN: llc -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GFX11 %s -; RUN: llc -global-isel -march=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GFX11 %s - -; no-rtn - -; GFX11: BUFFER_ATOMIC_ADD_F32_OFFEN -define amdgpu_ps void @raw_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__vgpr_voffset_plus4095__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { - %voffset.add = add i32 %voffset, 4095 - %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset.add, i32 %soffset, i32 0) - ret void -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_OFFEN -define amdgpu_ps void @raw_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__vgpr_voffset__sgpr_soffset_slc(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 2) - ret void -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_OFFSET -define amdgpu_ps void @raw_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__vgpr_voffset_4095__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 4095, i32 %soffset, i32 0) - ret void -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_IDXEN -define amdgpu_ps void @struct_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__4095_voffset__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 4095, i32 %soffset, i32 0) - ret void -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_IDXEN -define amdgpu_ps void @struct_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__0_voffset__sgpr_soffset_slc(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 2) - ret void -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_BOTHEN -define amdgpu_ps void @struct_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__vgpr_voffset_plus4095__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { - %voffset.add = add i32 %voffset, 4095 - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset.add, i32 %soffset, i32 0) - ret void -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_BOTHEN -define amdgpu_ps void @xstruct_buffer_atomic_add_f32_noret__vgpr_val__sgpr_rsrc__vgpr_voffset__sgpr_soffset_slc(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) - ret void -} - - -; rtn - -; GFX11: BUFFER_ATOMIC_ADD_F32_OFFEN -define amdgpu_ps float @raw_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__vgpr_voffset_plus4095__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { - %voffset.add = add i32 %voffset, 4095 - %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset.add, i32 %soffset, i32 0) - ret float %ret -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_OFFEN -define amdgpu_ps float @raw_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__vgpr_voffset__sgpr_soffset_slc(float %val, <4 x i32> inreg %rsrc, i32 %voffset, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %voffset, i32 %soffset, i32 2) - ret float %ret -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_OFFSET -define amdgpu_ps float @raw_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__vgpr_voffset_4095__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 4095, i32 %soffset, i32 0) - ret float %ret -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_IDXEN -define amdgpu_ps float @struct_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__4095_voffset__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 4095, i32 %soffset, i32 0) - ret float %ret -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_IDXEN -define amdgpu_ps float @struct_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__0_voffset__sgpr_soffset_slc(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 0, i32 %soffset, i32 2) - ret float %ret -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_BOTHEN -define amdgpu_ps float @struct_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__vgpr_voffset_plus4095__sgpr_soffset(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { - %voffset.add = add i32 %voffset, 4095 - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset.add, i32 %soffset, i32 0) - ret float %ret -} - -; GFX11: BUFFER_ATOMIC_ADD_F32_BOTHEN -define amdgpu_ps float @xstruct_buffer_atomic_add_f32_ret__vgpr_val__sgpr_rsrc__vgpr_voffset__sgpr_soffset_slc(float %val, <4 x i32> inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) { - %ret = call float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float %val, <4 x i32> %rsrc, i32 %vindex, i32 %voffset, i32 %soffset, i32 2) - ret float %ret -} - -declare float @llvm.amdgcn.raw.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32 immarg) #0 -declare float @llvm.amdgcn.struct.buffer.atomic.fadd.f32(float, <4 x i32>, i32, i32, i32, i32 immarg) #0 -attributes #0 = { nounwind } Index: llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fadd.ll =================================================================== --- llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fadd.ll +++ llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fadd.ll @@ -2,6 +2,401 @@ ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -atomic-expand %s | FileCheck -check-prefix=CI %s ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -atomic-expand %s | FileCheck -check-prefix=GFX9 %s ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -atomic-expand %s | FileCheck -check-prefix=GFX908 %s +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -atomic-expand %s | FileCheck -check-prefix=GFX90a %s +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx940 -atomic-expand %s | FileCheck -check-prefix=GFX940 %s +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -atomic-expand %s | FileCheck -check-prefix=GFX11 %s + +define void @test_atomicrmw_fadd_f32_global_no_use_unsafe(float addrspace(1)* %ptr, float %value) #0 { +; CI-LABEL: @test_atomicrmw_fadd_f32_global_no_use_unsafe( +; CI-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; CI-NEXT: br label [[ATOMICRMW_START:%.*]] +; CI: atomicrmw.start: +; CI-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; CI-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; CI-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; CI-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; CI-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; CI-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; CI-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; CI-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; CI-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; CI-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; CI: atomicrmw.end: +; CI-NEXT: ret void +; +; GFX9-LABEL: @test_atomicrmw_fadd_f32_global_no_use_unsafe( +; GFX9-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX9-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX9: atomicrmw.start: +; GFX9-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX9-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX9-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX9-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX9-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX9-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX9-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX9-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX9-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX9-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX9: atomicrmw.end: +; GFX9-NEXT: ret void +; +; GFX908-LABEL: @test_atomicrmw_fadd_f32_global_no_use_unsafe( +; GFX908-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX908-NEXT: ret void +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global_no_use_unsafe( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX90a-NEXT: ret void +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global_no_use_unsafe( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX940-NEXT: ret void +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global_no_use_unsafe( +; GFX11-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX11-NEXT: ret void +; + %res = atomicrmw fadd float addrspace(1)* %ptr, float %value syncscope("wavefront") monotonic + ret void +} + +define float @test_atomicrmw_fadd_f32_global_unsafe(float addrspace(1)* %ptr, float %value) #0 { +; CI-LABEL: @test_atomicrmw_fadd_f32_global_unsafe( +; CI-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; CI-NEXT: br label [[ATOMICRMW_START:%.*]] +; CI: atomicrmw.start: +; CI-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; CI-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; CI-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; CI-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; CI-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; CI-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; CI-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; CI-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; CI-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; CI-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; CI: atomicrmw.end: +; CI-NEXT: ret float [[TMP6]] +; +; GFX9-LABEL: @test_atomicrmw_fadd_f32_global_unsafe( +; GFX9-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX9-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX9: atomicrmw.start: +; GFX9-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX9-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX9-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX9-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX9-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX9-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX9-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX9-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX9-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX9-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX9: atomicrmw.end: +; GFX9-NEXT: ret float [[TMP6]] +; +; GFX908-LABEL: @test_atomicrmw_fadd_f32_global_unsafe( +; GFX908-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX908: atomicrmw.start: +; GFX908-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX908-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX908-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX908-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX908-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX908-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX908-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX908: atomicrmw.end: +; GFX908-NEXT: ret float [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global_unsafe( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX90a-NEXT: ret float [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global_unsafe( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global_unsafe( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret float [[TMP6]] +; + %res = atomicrmw fadd float addrspace(1)* %ptr, float %value syncscope("wavefront") monotonic + ret float %res +} + +define double @test_atomicrmw_fadd_f64_global_unsafe(double addrspace(1)* %ptr, double %value) #0 { +; CI-LABEL: @test_atomicrmw_fadd_f64_global_unsafe( +; CI-NEXT: [[TMP1:%.*]] = load double, double addrspace(1)* [[PTR:%.*]], align 8 +; CI-NEXT: br label [[ATOMICRMW_START:%.*]] +; CI: atomicrmw.start: +; CI-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; CI-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; CI-NEXT: [[TMP2:%.*]] = bitcast double addrspace(1)* [[PTR]] to i64 addrspace(1)* +; CI-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; CI-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; CI-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(1)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; CI-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; CI-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; CI-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; CI-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; CI: atomicrmw.end: +; CI-NEXT: ret double [[TMP6]] +; +; GFX9-LABEL: @test_atomicrmw_fadd_f64_global_unsafe( +; GFX9-NEXT: [[TMP1:%.*]] = load double, double addrspace(1)* [[PTR:%.*]], align 8 +; GFX9-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX9: atomicrmw.start: +; GFX9-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX9-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX9-NEXT: [[TMP2:%.*]] = bitcast double addrspace(1)* [[PTR]] to i64 addrspace(1)* +; GFX9-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX9-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX9-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(1)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; GFX9-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX9-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX9-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX9-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX9: atomicrmw.end: +; GFX9-NEXT: ret double [[TMP6]] +; +; GFX908-LABEL: @test_atomicrmw_fadd_f64_global_unsafe( +; GFX908-NEXT: [[TMP1:%.*]] = load double, double addrspace(1)* [[PTR:%.*]], align 8 +; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX908: atomicrmw.start: +; GFX908-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX908-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX908-NEXT: [[TMP2:%.*]] = bitcast double addrspace(1)* [[PTR]] to i64 addrspace(1)* +; GFX908-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX908-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX908-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(1)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX908-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX908: atomicrmw.end: +; GFX908-NEXT: ret double [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f64_global_unsafe( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd double addrspace(1)* [[PTR:%.*]], double [[VALUE:%.*]] syncscope("wavefront") monotonic, align 8 +; GFX90a-NEXT: ret double [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f64_global_unsafe( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd double addrspace(1)* [[PTR:%.*]], double [[VALUE:%.*]] syncscope("wavefront") monotonic, align 8 +; GFX940-NEXT: ret double [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f64_global_unsafe( +; GFX11-NEXT: [[TMP1:%.*]] = load double, double addrspace(1)* [[PTR:%.*]], align 8 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast double addrspace(1)* [[PTR]] to i64 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(1)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret double [[TMP6]] +; + %res = atomicrmw fadd double addrspace(1)* %ptr, double %value syncscope("wavefront") monotonic + ret double %res +} + +define float @test_atomicrmw_fadd_f32_flat_unsafe(float* %ptr, float %value) #0 { +; CI-LABEL: @test_atomicrmw_fadd_f32_flat_unsafe( +; CI-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; CI-NEXT: br label [[ATOMICRMW_START:%.*]] +; CI: atomicrmw.start: +; CI-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; CI-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; CI-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; CI-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; CI-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; CI-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; CI-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; CI-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; CI-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; CI-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; CI: atomicrmw.end: +; CI-NEXT: ret float [[TMP6]] +; +; GFX9-LABEL: @test_atomicrmw_fadd_f32_flat_unsafe( +; GFX9-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; GFX9-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX9: atomicrmw.start: +; GFX9-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX9-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX9-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; GFX9-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX9-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX9-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX9-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX9-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX9-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX9-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX9: atomicrmw.end: +; GFX9-NEXT: ret float [[TMP6]] +; +; GFX908-LABEL: @test_atomicrmw_fadd_f32_flat_unsafe( +; GFX908-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX908: atomicrmw.start: +; GFX908-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX908-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX908-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; GFX908-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX908-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX908-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX908-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX908: atomicrmw.end: +; GFX908-NEXT: ret float [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_flat_unsafe( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret float [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_flat_unsafe( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("wavefront") monotonic, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_flat_unsafe( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret float [[TMP6]] +; + %res = atomicrmw fadd float* %ptr, float %value syncscope("wavefront") monotonic + ret float %res +} + +define double @test_atomicrmw_fadd_f64_flat_unsafe(double* %ptr, double %value) #0 { +; CI-LABEL: @test_atomicrmw_fadd_f64_flat_unsafe( +; CI-NEXT: [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8 +; CI-NEXT: br label [[ATOMICRMW_START:%.*]] +; CI: atomicrmw.start: +; CI-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; CI-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; CI-NEXT: [[TMP2:%.*]] = bitcast double* [[PTR]] to i64* +; CI-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; CI-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; CI-NEXT: [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; CI-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; CI-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; CI-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; CI-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; CI: atomicrmw.end: +; CI-NEXT: ret double [[TMP6]] +; +; GFX9-LABEL: @test_atomicrmw_fadd_f64_flat_unsafe( +; GFX9-NEXT: [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8 +; GFX9-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX9: atomicrmw.start: +; GFX9-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX9-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX9-NEXT: [[TMP2:%.*]] = bitcast double* [[PTR]] to i64* +; GFX9-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX9-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX9-NEXT: [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; GFX9-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX9-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX9-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX9-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX9: atomicrmw.end: +; GFX9-NEXT: ret double [[TMP6]] +; +; GFX908-LABEL: @test_atomicrmw_fadd_f64_flat_unsafe( +; GFX908-NEXT: [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8 +; GFX908-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX908: atomicrmw.start: +; GFX908-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX908-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX908-NEXT: [[TMP2:%.*]] = bitcast double* [[PTR]] to i64* +; GFX908-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX908-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX908-NEXT: [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; GFX908-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX908-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX908-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX908: atomicrmw.end: +; GFX908-NEXT: ret double [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f64_flat_unsafe( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd double* [[PTR:%.*]], double [[VALUE:%.*]] syncscope("wavefront") monotonic, align 8 +; GFX90a-NEXT: ret double [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f64_flat_unsafe( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd double* [[PTR:%.*]], double [[VALUE:%.*]] syncscope("wavefront") monotonic, align 8 +; GFX940-NEXT: ret double [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f64_flat_unsafe( +; GFX11-NEXT: [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast double* [[PTR]] to i64* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] syncscope("wavefront") monotonic monotonic, align 8 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret double [[TMP6]] +; + %res = atomicrmw fadd double* %ptr, double %value syncscope("wavefront") monotonic + ret double %res +} define float @test_atomicrmw_fadd_f32_flat(float* %ptr, float %value) { ; CI-LABEL: @test_atomicrmw_fadd_f32_flat( @@ -54,6 +449,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret float [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_flat( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret float [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_flat( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_flat( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float* [[PTR]] to i32* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret float [[TMP6]] ; %res = atomicrmw fadd float* %ptr, float %value seq_cst ret float %res @@ -110,6 +543,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret float [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret float [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret float [[TMP6]] ; %res = atomicrmw fadd float addrspace(1)* %ptr, float %value seq_cst ret float %res @@ -166,6 +637,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret void +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global_no_use_ieee( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret void +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global_no_use_ieee( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX940-NEXT: ret void +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global_no_use_ieee( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret void ; %res = atomicrmw fadd float addrspace(1)* %ptr, float %value seq_cst ret void @@ -209,6 +718,31 @@ ; GFX908-LABEL: @test_atomicrmw_fadd_f32_global_no_use_denorm_flush( ; GFX908-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 ; GFX908-NEXT: ret void +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global_no_use_denorm_flush( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret void +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global_no_use_denorm_flush( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX940-NEXT: ret void +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global_no_use_denorm_flush( +; GFX11-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX11-NEXT: ret void ; %res = atomicrmw fadd float addrspace(1)* %ptr, float %value seq_cst ret void @@ -239,6 +773,18 @@ ; GFX908-LABEL: @test_atomicrmw_fadd_f32_local( ; GFX908-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(3)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 ; GFX908-NEXT: ret float [[RES]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_local( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(3)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX90a-NEXT: ret float [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_local( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(3)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_local( +; GFX11-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(3)* [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 +; GFX11-NEXT: ret float [[RES]] ; %res = atomicrmw fadd float addrspace(3)* %ptr, float %value seq_cst ret float %res @@ -256,6 +802,18 @@ ; GFX908-LABEL: @test_atomicrmw_fadd_f16_flat( ; GFX908-NEXT: [[RES:%.*]] = atomicrmw fadd half* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 ; GFX908-NEXT: ret half [[RES]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f16_flat( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd half* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX90a-NEXT: ret half [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f16_flat( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd half* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX940-NEXT: ret half [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f16_flat( +; GFX11-NEXT: [[RES:%.*]] = atomicrmw fadd half* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX11-NEXT: ret half [[RES]] ; %res = atomicrmw fadd half* %ptr, half %value seq_cst ret half %res @@ -273,6 +831,18 @@ ; GFX908-LABEL: @test_atomicrmw_fadd_f16_global( ; GFX908-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(1)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 ; GFX908-NEXT: ret half [[RES]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f16_global( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(1)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX90a-NEXT: ret half [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f16_global( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(1)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX940-NEXT: ret half [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f16_global( +; GFX11-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(1)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX11-NEXT: ret half [[RES]] ; %res = atomicrmw fadd half addrspace(1)* %ptr, half %value seq_cst ret half %res @@ -290,6 +860,18 @@ ; GFX908-LABEL: @test_atomicrmw_fadd_f16_local( ; GFX908-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(3)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 ; GFX908-NEXT: ret half [[RES]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f16_local( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(3)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX90a-NEXT: ret half [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f16_local( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(3)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX940-NEXT: ret half [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f16_local( +; GFX11-NEXT: [[RES:%.*]] = atomicrmw fadd half addrspace(3)* [[PTR:%.*]], half [[VALUE:%.*]] seq_cst, align 2 +; GFX11-NEXT: ret half [[RES]] ; %res = atomicrmw fadd half addrspace(3)* %ptr, half %value seq_cst ret half %res @@ -346,6 +928,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret double [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f64_flat( +; GFX90a-NEXT: [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast double* [[PTR]] to i64* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret double [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f64_flat( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd double* [[PTR:%.*]], double [[VALUE:%.*]] seq_cst, align 8 +; GFX940-NEXT: ret double [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f64_flat( +; GFX11-NEXT: [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast double* [[PTR]] to i64* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret double [[TMP6]] ; %res = atomicrmw fadd double* %ptr, double %value seq_cst ret double %res @@ -402,6 +1022,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret double [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f64_global( +; GFX90a-NEXT: [[TMP1:%.*]] = load double, double addrspace(1)* [[PTR:%.*]], align 8 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast double addrspace(1)* [[PTR]] to i64 addrspace(1)* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(1)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret double [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f64_global( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd double addrspace(1)* [[PTR:%.*]], double [[VALUE:%.*]] seq_cst, align 8 +; GFX940-NEXT: ret double [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f64_global( +; GFX11-NEXT: [[TMP1:%.*]] = load double, double addrspace(1)* [[PTR:%.*]], align 8 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast double addrspace(1)* [[PTR]] to i64 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(1)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret double [[TMP6]] ; %res = atomicrmw fadd double addrspace(1)* %ptr, double %value seq_cst ret double %res @@ -458,6 +1116,31 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret double [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f64_local( +; GFX90a-NEXT: [[RES:%.*]] = atomicrmw fadd double addrspace(3)* [[PTR:%.*]], double [[VALUE:%.*]] seq_cst, align 8 +; GFX90a-NEXT: ret double [[RES]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f64_local( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd double addrspace(3)* [[PTR:%.*]], double [[VALUE:%.*]] seq_cst, align 8 +; GFX940-NEXT: ret double [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f64_local( +; GFX11-NEXT: [[TMP1:%.*]] = load double, double addrspace(3)* [[PTR:%.*]], align 8 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast double addrspace(3)* [[PTR]] to i64 addrspace(3)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast double [[NEW]] to i64 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i64 addrspace(3)* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret double [[TMP6]] ; %res = atomicrmw fadd double addrspace(3)* %ptr, double %value seq_cst ret double %res @@ -514,6 +1197,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret float [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global_agent( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("agent") monotonic monotonic, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret float [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global_agent( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("agent") monotonic, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global_agent( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("agent") monotonic monotonic, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret float [[TMP6]] ; %res = atomicrmw fadd float addrspace(1)* %ptr, float %value syncscope("agent") monotonic ret float %res @@ -570,6 +1291,44 @@ ; GFX908-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] ; GFX908: atomicrmw.end: ; GFX908-NEXT: ret float [[TMP6]] +; +; GFX90a-LABEL: @test_atomicrmw_fadd_f32_global_one_as( +; GFX90a-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX90a-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX90a: atomicrmw.start: +; GFX90a-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX90a-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX90a-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX90a-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX90a-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX90a-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("one-as") monotonic monotonic, align 4 +; GFX90a-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX90a-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX90a-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX90a-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX90a: atomicrmw.end: +; GFX90a-NEXT: ret float [[TMP6]] +; +; GFX940-LABEL: @test_atomicrmw_fadd_f32_global_one_as( +; GFX940-NEXT: [[RES:%.*]] = atomicrmw fadd float addrspace(1)* [[PTR:%.*]], float [[VALUE:%.*]] syncscope("one-as") monotonic, align 4 +; GFX940-NEXT: ret float [[RES]] +; +; GFX11-LABEL: @test_atomicrmw_fadd_f32_global_one_as( +; GFX11-NEXT: [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4 +; GFX11-NEXT: br label [[ATOMICRMW_START:%.*]] +; GFX11: atomicrmw.start: +; GFX11-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +; GFX11-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +; GFX11-NEXT: [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)* +; GFX11-NEXT: [[TMP3:%.*]] = bitcast float [[NEW]] to i32 +; GFX11-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +; GFX11-NEXT: [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] syncscope("one-as") monotonic monotonic, align 4 +; GFX11-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +; GFX11-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +; GFX11-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +; GFX11-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +; GFX11: atomicrmw.end: +; GFX11-NEXT: ret float [[TMP6]] ; %res = atomicrmw fadd float addrspace(1)* %ptr, float %value syncscope("one-as") monotonic ret float %res