diff --git a/lib/HLSL/HLOperations.cpp b/lib/HLSL/HLOperations.cpp index 2f5e019c3..a2ace9307 100644 --- a/lib/HLSL/HLOperations.cpp +++ b/lib/HLSL/HLOperations.cpp @@ -455,9 +455,23 @@ static void SetHLFunctionAttribute(Function *F, HLOpcodeGroup group, F->addFnAttr(Attribute::ReadNone); F->addFnAttr(Attribute::NoUnwind); } break; + case HLOpcodeGroup::HLIntrinsic: { + IntrinsicOp intrinsicOp = static_cast(opcode); + switch (intrinsicOp) { + default: + break; + case IntrinsicOp::IOP_DeviceMemoryBarrierWithGroupSync: + case IntrinsicOp::IOP_DeviceMemoryBarrier: + case IntrinsicOp::IOP_GroupMemoryBarrierWithGroupSync: + case IntrinsicOp::IOP_GroupMemoryBarrier: + case IntrinsicOp::IOP_AllMemoryBarrierWithGroupSync: + case IntrinsicOp::IOP_AllMemoryBarrier: + F->addFnAttr(Attribute::NoDuplicate); + break; + } + } break; case HLOpcodeGroup::NotHL: case HLOpcodeGroup::HLExtIntrinsic: - case HLOpcodeGroup::HLIntrinsic: case HLOpcodeGroup::HLSelect: case HLOpcodeGroup::NumOfHLOps: // No default attributes for these opcodes. diff --git a/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/barrier/no_dup.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/barrier/no_dup.hlsl new file mode 100644 index 000000000..605c4da4c --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/barrier/no_dup.hlsl @@ -0,0 +1,33 @@ +// RUN: %dxc -T cs_6_3 %s | FileCheck %s + +// Make sure only 2 barrier. +// CHECK: call void @dx.op.barrier(i32 80, i32 9) +// CHECK: call void @dx.op.barrier(i32 80, i32 9) +// CHECK-NOT: call void @dx.op.barrier(i32 80, i32 9) + +RWStructuredBuffer _CoarseStencilBuffer; +uint stencilBufferWidth; + +groupshared uint g_GroupsharedValue; + +[numthreads(8, 8, 1)] +void main(uint3 groupId : SV_GroupID, + uint threadIndex : SV_GroupIndex) +{ + uint threadValue = 1 << (threadIndex/2); + + bool isFirstThreadInGroup = threadIndex == 0; + + if (isFirstThreadInGroup) + g_GroupsharedValue = 0; + + GroupMemoryBarrierWithGroupSync(); + InterlockedOr(g_GroupsharedValue, threadValue); + GroupMemoryBarrierWithGroupSync(); + + if (isFirstThreadInGroup) + { + uint addressIndex = groupId.y * stencilBufferWidth + groupId.x; + _CoarseStencilBuffer[addressIndex] = g_GroupsharedValue; + } +} \ No newline at end of file