Skip to content

Commit f95a6d7

Browse files
authored
Translate atomicrmw fsub into FNegate and AtomicFAddEXT (#1780)
Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
1 parent a8b0c8e commit f95a6d7

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,16 +2172,15 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
21722172
AtomicRMWInst::BinOp Op = ARMW->getOperation();
21732173
bool SupportedAtomicInst =
21742174
AtomicRMWInst::isFPOperation(Op)
2175-
? (Op == AtomicRMWInst::FAdd || Op == AtomicRMWInst::FMin ||
2176-
Op == AtomicRMWInst::FMax)
2175+
? (Op == AtomicRMWInst::FAdd || Op == AtomicRMWInst::FSub ||
2176+
Op == AtomicRMWInst::FMin || Op == AtomicRMWInst::FMax)
21772177
: Op != AtomicRMWInst::Nand;
21782178
if (!BM->getErrorLog().checkError(
21792179
SupportedAtomicInst, SPIRVEC_InvalidInstruction, V,
21802180
"Atomic " + AtomicRMWInst::getOperationName(Op).str() +
21812181
" is not supported in SPIR-V!\n"))
21822182
return nullptr;
21832183

2184-
spv::Op OC = LLVMSPIRVAtomicRmwOpCodeMap::map(Op);
21852184
AtomicOrderingCABI Ordering = llvm::toCABI(ARMW->getOrdering());
21862185
auto MemSem = OCLMemOrderMap::map(static_cast<OCLMemOrderKind>(Ordering));
21872186
std::vector<Value *> Operands(4);
@@ -2195,9 +2194,18 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
21952194
Operands[1] = getUInt32(M, spv::ScopeDevice);
21962195
Operands[2] = getUInt32(M, MemSem);
21972196
Operands[3] = ARMW->getValOperand();
2198-
std::vector<SPIRVId> Ops = BM->getIds(transValue(Operands, BB));
2197+
std::vector<SPIRVValue *> OpVals = transValue(Operands, BB);
2198+
std::vector<SPIRVId> Ops = BM->getIds(OpVals);
21992199
SPIRVType *Ty = transType(ARMW->getType());
22002200

2201+
spv::Op OC;
2202+
if (Op == AtomicRMWInst::FSub) {
2203+
// Implement FSub through FNegate and AtomicFAddExt
2204+
Ops[3] = BM->addUnaryInst(OpFNegate, Ty, OpVals[3], BB)->getId();
2205+
OC = OpAtomicFAddEXT;
2206+
} else
2207+
OC = LLVMSPIRVAtomicRmwOpCodeMap::map(Op);
2208+
22012209
return mapValue(V, BM->addInstTemplate(OC, Ops, BB, Ty));
22022210
}
22032211

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llvm-as -opaque-pointers=0 < %s -o %t.bc
2+
; RUN: llvm-spirv -opaque-pointers=0 --spirv-ext=+SPV_EXT_shader_atomic_float_add %t.bc -o %t.spv
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv -to-text %t.spv -o - | FileCheck --check-prefix=CHECK-SPIRV %s
5+
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc -o - | FileCheck %s --check-prefixes=CHECK-LLVM
8+
9+
; CHECK-SPIRV-DAG: Extension "SPV_EXT_shader_atomic_float_add"
10+
; CHECK-SPIRV-DAG: Capability AtomicFloat64AddEXT
11+
; CHECK-SPIRV: TypeInt [[Int:[0-9]+]] 32 0
12+
; CHECK-SPIRV-DAG: Constant [[Int]] [[Scope_Device:[0-9]+]] 1 {{$}}
13+
; CHECK-SPIRV-DAG: Constant [[Int]] [[MemSem_SequentiallyConsistent:[0-9]+]] 16
14+
; CHECK-SPIRV: TypeFloat [[Double:[0-9]+]] 64
15+
; CHECK-SPIRV: Variable {{[0-9]+}} [[DoublePointer:[0-9]+]]
16+
; CHECK-SPIRV: Constant [[Double]] [[DoubleValue:[0-9]+]] 0 1078263808
17+
18+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
19+
target triple = "spir64"
20+
21+
@f = common dso_local local_unnamed_addr addrspace(1) global double 0.000000e+00, align 8
22+
23+
; Function Attrs: nounwind
24+
define dso_local spir_func void @test_atomicrmw_fadd() local_unnamed_addr #0 {
25+
entry:
26+
%0 = atomicrmw fsub double addrspace(1)* @f, double 42.000000e+00 seq_cst
27+
; CHECK-SPIRV: FNegate [[Double]] [[NegateValue:[0-9]+]] [[DoubleValue]]
28+
; CHECK-SPIRV: AtomicFAddEXT [[Double]] {{[0-9]+}} [[DoublePointer]] [[Scope_Device]] [[MemSem_SequentiallyConsistent]] [[NegateValue]]
29+
; CHECK-LLVM: [[FNegateLLVM:%[0-9]+]] = fneg double 4.200000e+01
30+
; CHECK-LLVM: call spir_func double {{.*}}atomic_add{{.*}}(double addrspace(1)* @f, double [[FNegateLLVM]])
31+
ret void
32+
}
33+
34+
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
35+
36+
!llvm.module.flags = !{!0}
37+
38+
!0 = !{i32 1, !"wchar_size", i32 4}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llvm-as -opaque-pointers=0 < %s -o %t.bc
2+
; RUN: llvm-spirv -opaque-pointers=0 --spirv-ext=+SPV_EXT_shader_atomic_float_add %t.bc -o %t.spv
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv -to-text %t.spv -o - | FileCheck --check-prefix=CHECK-SPIRV %s
5+
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc -o - | FileCheck %s --check-prefixes=CHECK-LLVM
8+
9+
; CHECK-SPIRV-DAG: Extension "SPV_EXT_shader_atomic_float_add"
10+
; CHECK-SPIRV-DAG: Capability AtomicFloat32AddEXT
11+
; CHECK-SPIRV: TypeInt [[Int:[0-9]+]] 32 0
12+
; CHECK-SPIRV-DAG: Constant [[Int]] [[Scope_Device:[0-9]+]] 1 {{$}}
13+
; CHECK-SPIRV-DAG: Constant [[Int]] [[MemSem_SequentiallyConsistent:[0-9]+]] 16
14+
; CHECK-SPIRV: TypeFloat [[Float:[0-9]+]] 32
15+
; CHECK-SPIRV: Variable {{[0-9]+}} [[FPPointer:[0-9]+]]
16+
; CHECK-SPIRV: Constant [[Float]] [[FPValue:[0-9]+]] 1109917696
17+
18+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
19+
target triple = "spir64"
20+
21+
@f = common dso_local local_unnamed_addr addrspace(1) global float 0.000000e+00, align 4
22+
23+
; Function Attrs: nounwind
24+
define dso_local spir_func void @test_atomicrmw_fadd() local_unnamed_addr #0 {
25+
entry:
26+
%0 = atomicrmw fsub float addrspace(1)* @f, float 42.000000e+00 seq_cst
27+
; CHECK-SPIRV: FNegate [[Float]] [[NegateValue:[0-9]+]] [[FPValue]]
28+
; CHECK-SPIRV: AtomicFAddEXT [[Float]] {{[0-9]+}} [[FPPointer]] [[Scope_Device]] [[MemSem_SequentiallyConsistent]] [[NegateValue]]
29+
; CHECK-LLVM: [[FNegateLLVM:%[0-9]+]] = fneg float 4.200000e+01
30+
; CHECK-LLVM: call spir_func float {{.*}}atomic_add{{.*}}(float addrspace(1)* @f, float [[FNegateLLVM]])
31+
ret void
32+
}
33+
34+
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
35+
36+
!llvm.module.flags = !{!0}
37+
38+
!0 = !{i32 1, !"wchar_size", i32 4}

0 commit comments

Comments
 (0)