Fixed InterlockedCompareExchange failing validation (#2284)

The code handled instruction addrspacecasts but not constant expression ones. Refactored into a common method between two code paths.
This commit is contained in:
Tristan Labelle 2019-06-24 10:34:38 -07:00 коммит произвёл GitHub
Родитель 109bbf0f8a
Коммит 9799235a6a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 43 добавлений и 11 удалений

Просмотреть файл

@ -4034,18 +4034,22 @@ void TranslateSharedMemAtomicBinOp(CallInst *CI, IntrinsicOp IOP, Value *addr) {
CI->getArgOperand(HLOperandIndex::kInterlockedOriginalValueOpIndex));
}
static Value* SkipAddrSpaceCast(Value* Ptr) {
if (AddrSpaceCastInst *CastInst = dyn_cast<AddrSpaceCastInst>(Ptr))
return CastInst->getOperand(0);
else if (ConstantExpr *ConstExpr = dyn_cast<ConstantExpr>(Ptr)) {
if (ConstExpr->getOpcode() == Instruction::AddrSpaceCast) {
return ConstExpr->getOperand(0);
}
}
return Ptr;
}
Value *TranslateIopAtomicBinaryOperation(CallInst *CI, IntrinsicOp IOP,
DXIL::OpCode opcode,
HLOperationLowerHelper &helper, HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
Value *addr = CI->getArgOperand(HLOperandIndex::kInterlockedDestOpIndex);
// Get the original addr from cast.
if (CastInst *castInst = dyn_cast<CastInst>(addr))
addr = castInst->getOperand(0);
else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(addr)) {
if (CE->getOpcode() == Instruction::AddrSpaceCast) {
addr = CE->getOperand(0);
}
}
addr = SkipAddrSpaceCast(addr);
unsigned addressSpace = addr->getType()->getPointerAddressSpace();
if (addressSpace == DXIL::kTGSMAddrSpace)
@ -4081,9 +4085,7 @@ Value *TranslateIopAtomicCmpXChg(CallInst *CI, IntrinsicOp IOP,
DXIL::OpCode opcode,
HLOperationLowerHelper &helper, HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
Value *addr = CI->getArgOperand(HLOperandIndex::kInterlockedDestOpIndex);
// Get the original addr from cast.
if (CastInst *castInst = dyn_cast<CastInst>(addr))
addr = castInst->getOperand(0);
addr = SkipAddrSpaceCast(addr);
unsigned addressSpace = addr->getType()->getPointerAddressSpace();
if (addressSpace == DXIL::kTGSMAddrSpace)

Просмотреть файл

@ -0,0 +1,30 @@
// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
groupshared int sharedInt[1];
groupshared uint sharedUInt[1];
[numthreads(8, 8, 1)]
void main()
{
int v;
// CHECK: cmpxchg
InterlockedCompareExchange(sharedInt[0], -1, -2, v);
// CHECK: atomicrmw xchg
InterlockedExchange(sharedInt[0], -1, v);
// CHECK: atomicrmw add
InterlockedAdd(sharedInt[0], -1);
// CHECK: atomicrmw and
InterlockedAnd(sharedInt[0], -1);
// CHECK: atomicrmw or
InterlockedOr(sharedInt[0], -1);
// CHECK: atomicrmw xor
InterlockedXor(sharedInt[0], -1);
// CHECK: atomicrmw max
InterlockedMax(sharedInt[0], -1); // -1 to workaround GitHub #2283
// CHECK: atomicrmw min
InterlockedMin(sharedInt[0], -1); // -1 to workaround GitHub #2283
// CHECK: atomicrmw umax
InterlockedMax(sharedUInt[0], (uint)1);
// CHECK: atomicrmw umin
InterlockedMin(sharedUInt[0], (uint)1);
}