From: Nick Sarnie Date: Thu, 22 Dec 2022 09:47:24 +0000 (-0500) Subject: [PATCH 77/79] [Backport to 15] Translate atomicrmw fsub into FNegate and AtomicFAddEX... X-Git-Tag: archive/raspbian/15.0.0-6+rpi1^2~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=fa126e44e393be9c8ac078142f254411b88bf182;p=spirv-llvm-translator-15.git [PATCH 77/79] [Backport to 15] Translate atomicrmw fsub into FNegate and AtomicFAddEXT (#1780) Signed-off-by: Sarnie, Nick Gbp-Pq: Name 0077-Backport-to-15-Translate-atomicrmw-fsub-into-FNegate.patch --- diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index c58c2d7..013e519 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -2191,16 +2191,16 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB, if (AtomicRMWInst *ARMW = dyn_cast(V)) { AtomicRMWInst::BinOp Op = ARMW->getOperation(); - bool SupportedAtomicInst = AtomicRMWInst::isFPOperation(Op) - ? Op == AtomicRMWInst::FAdd - : Op != AtomicRMWInst::Nand; + bool SupportedAtomicInst = + AtomicRMWInst::isFPOperation(Op) + ? (Op == AtomicRMWInst::FAdd || Op == AtomicRMWInst::FSub) + : Op != AtomicRMWInst::Nand; if (!BM->getErrorLog().checkError( SupportedAtomicInst, SPIRVEC_InvalidInstruction, V, "Atomic " + AtomicRMWInst::getOperationName(Op).str() + " is not supported in SPIR-V!\n")) return nullptr; - spv::Op OC = LLVMSPIRVAtomicRmwOpCodeMap::map(Op); AtomicOrderingCABI Ordering = llvm::toCABI(ARMW->getOrdering()); auto MemSem = OCLMemOrderMap::map(static_cast(Ordering)); std::vector Operands(4); @@ -2214,9 +2214,18 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB, Operands[1] = getUInt32(M, spv::ScopeDevice); Operands[2] = getUInt32(M, MemSem); Operands[3] = ARMW->getValOperand(); - std::vector Ops = BM->getIds(transValue(Operands, BB)); + std::vector OpVals = transValue(Operands, BB); + std::vector Ops = BM->getIds(OpVals); SPIRVType *Ty = transType(ARMW->getType()); + spv::Op OC; + if (Op == AtomicRMWInst::FSub) { + // Implement FSub through FNegate and AtomicFAddExt + Ops[3] = BM->addUnaryInst(OpFNegate, Ty, OpVals[3], BB)->getId(); + OC = OpAtomicFAddEXT; + } else + OC = LLVMSPIRVAtomicRmwOpCodeMap::map(Op); + return mapValue(V, BM->addInstTemplate(OC, Ops, BB, Ty)); } diff --git a/test/extensions/EXT/SPV_EXT_shader_atomic_float_/atomicrmw_fsub_double.ll b/test/extensions/EXT/SPV_EXT_shader_atomic_float_/atomicrmw_fsub_double.ll new file mode 100644 index 0000000..af3da7e --- /dev/null +++ b/test/extensions/EXT/SPV_EXT_shader_atomic_float_/atomicrmw_fsub_double.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as -opaque-pointers=0 < %s -o %t.bc +; RUN: llvm-spirv -opaque-pointers=0 --spirv-ext=+SPV_EXT_shader_atomic_float_add %t.bc -o %t.spv +; RUN: spirv-val %t.spv +; RUN: llvm-spirv -to-text %t.spv -o - | FileCheck --check-prefix=CHECK-SPIRV %s + +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc -o - | FileCheck %s --check-prefixes=CHECK-LLVM + +; CHECK-SPIRV-DAG: Extension "SPV_EXT_shader_atomic_float_add" +; CHECK-SPIRV-DAG: Capability AtomicFloat64AddEXT +; CHECK-SPIRV: TypeInt [[Int:[0-9]+]] 32 0 +; CHECK-SPIRV-DAG: Constant [[Int]] [[Scope_Device:[0-9]+]] 1 {{$}} +; CHECK-SPIRV-DAG: Constant [[Int]] [[MemSem_SequentiallyConsistent:[0-9]+]] 16 +; CHECK-SPIRV: TypeFloat [[Double:[0-9]+]] 64 +; CHECK-SPIRV: Variable {{[0-9]+}} [[DoublePointer:[0-9]+]] +; CHECK-SPIRV: Constant [[Double]] [[DoubleValue:[0-9]+]] 0 1078263808 + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" +target triple = "spir64" + +@f = common dso_local local_unnamed_addr addrspace(1) global double 0.000000e+00, align 8 + +; Function Attrs: nounwind +define dso_local spir_func void @test_atomicrmw_fadd() local_unnamed_addr #0 { +entry: + %0 = atomicrmw fsub double addrspace(1)* @f, double 42.000000e+00 seq_cst +; CHECK-SPIRV: FNegate [[Double]] [[NegateValue:[0-9]+]] [[DoubleValue]] +; CHECK-SPIRV: AtomicFAddEXT [[Double]] {{[0-9]+}} [[DoublePointer]] [[Scope_Device]] [[MemSem_SequentiallyConsistent]] [[NegateValue]] +; CHECK-LLVM: [[FNegateLLVM:%[0-9]+]] = fneg double 4.200000e+01 +; CHECK-LLVM: call spir_func double {{.*}}atomic_add{{.*}}(double addrspace(1)* @f, double [[FNegateLLVM]]) + ret void +} + +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" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 1, !"wchar_size", i32 4} diff --git a/test/extensions/EXT/SPV_EXT_shader_atomic_float_/atomicrmw_fsub_float.ll b/test/extensions/EXT/SPV_EXT_shader_atomic_float_/atomicrmw_fsub_float.ll new file mode 100644 index 0000000..a9fab6b --- /dev/null +++ b/test/extensions/EXT/SPV_EXT_shader_atomic_float_/atomicrmw_fsub_float.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as -opaque-pointers=0 < %s -o %t.bc +; RUN: llvm-spirv -opaque-pointers=0 --spirv-ext=+SPV_EXT_shader_atomic_float_add %t.bc -o %t.spv +; RUN: spirv-val %t.spv +; RUN: llvm-spirv -to-text %t.spv -o - | FileCheck --check-prefix=CHECK-SPIRV %s + +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-dis -opaque-pointers=0 %t.rev.bc -o - | FileCheck %s --check-prefixes=CHECK-LLVM + +; CHECK-SPIRV-DAG: Extension "SPV_EXT_shader_atomic_float_add" +; CHECK-SPIRV-DAG: Capability AtomicFloat32AddEXT +; CHECK-SPIRV: TypeInt [[Int:[0-9]+]] 32 0 +; CHECK-SPIRV-DAG: Constant [[Int]] [[Scope_Device:[0-9]+]] 1 {{$}} +; CHECK-SPIRV-DAG: Constant [[Int]] [[MemSem_SequentiallyConsistent:[0-9]+]] 16 +; CHECK-SPIRV: TypeFloat [[Float:[0-9]+]] 32 +; CHECK-SPIRV: Variable {{[0-9]+}} [[FPPointer:[0-9]+]] +; CHECK-SPIRV: Constant [[Float]] [[FPValue:[0-9]+]] 1109917696 + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" +target triple = "spir64" + +@f = common dso_local local_unnamed_addr addrspace(1) global float 0.000000e+00, align 4 + +; Function Attrs: nounwind +define dso_local spir_func void @test_atomicrmw_fadd() local_unnamed_addr #0 { +entry: + %0 = atomicrmw fsub float addrspace(1)* @f, float 42.000000e+00 seq_cst +; CHECK-SPIRV: FNegate [[Float]] [[NegateValue:[0-9]+]] [[FPValue]] +; CHECK-SPIRV: AtomicFAddEXT [[Float]] {{[0-9]+}} [[FPPointer]] [[Scope_Device]] [[MemSem_SequentiallyConsistent]] [[NegateValue]] +; CHECK-LLVM: [[FNegateLLVM:%[0-9]+]] = fneg float 4.200000e+01 +; CHECK-LLVM: call spir_func float {{.*}}atomic_add{{.*}}(float addrspace(1)* @f, float [[FNegateLLVM]]) + ret void +} + +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" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 1, !"wchar_size", i32 4}