Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -150,8 +150,9 @@ unsigned Opc0 = Load0->getMachineOpcode(); unsigned Opc1 = Load1->getMachineOpcode(); - // Make sure both are actually loads. - if (!get(Opc0).mayLoad() || !get(Opc1).mayLoad()) + // Make sure both are actually loads (not stores or atomics). + if (!get(Opc0).mayLoad() || get(Opc0).mayStore() || !get(Opc1).mayLoad() || + get(Opc1).mayStore()) return false; if (isDS(Opc0) && isDS(Opc1)) { Index: test/CodeGen/AMDGPU/two-ds-atomics.ll =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/two-ds-atomics.ll @@ -0,0 +1,27 @@ +; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s + +; This test case asserted due to SIInstrInfo::areLoadsFromSameBasePtr mistaking +; an atomic for a load. + +; GCN-LABEL: _amdgpu_cs_main: +; GCN: ds_max_u32 +; GCN: ds_min_u32 + +@TileFarZ = external dso_local addrspace(3) global i32, align 16 +@TileNearZ = external dso_local addrspace(3) global i32, align 16 + +define amdgpu_cs void @_amdgpu_cs_main() local_unnamed_addr #0 { +.entry: + %tmp = tail call float @llvm.amdgcn.image.load.mip.2d.f32.i32(i32 1, i32 undef, i32 undef, i32 0, <8 x i32> undef, i32 0, i32 0) + %tmp1 = bitcast float %tmp to i32 + %tmp2 = atomicrmw volatile umax i32 addrspace(3)* @TileFarZ, i32 %tmp1 seq_cst + %tmp3 = atomicrmw volatile umin i32 addrspace(3)* @TileNearZ, i32 %tmp1 seq_cst + unreachable +} + +; Function Attrs: nounwind readonly +declare float @llvm.amdgcn.image.load.mip.2d.f32.i32(i32 immarg, i32, i32, i32, <8 x i32>, i32 immarg, i32 immarg) #1 + +attributes #0 = { "target-features" } +attributes #1 = { nounwind readonly } +