Skip to content

Commit 211c7dc

Browse files
authored
Implement SPV_INTEL_arithmetic_fence (#1099)
Implement SPV_INTEL_arithmetic_fence This extension creates support for a __fence keyword to prevent reordering and reassociating operations. Spec: intel/llvm#3914
1 parent 910aee7 commit 211c7dc

File tree

9 files changed

+72
-0
lines changed

9 files changed

+72
-0
lines changed

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ EXT(SPV_INTEL_fpga_invocation_pipelining_attributes)
4242
EXT(SPV_INTEL_token_type)
4343
EXT(SPV_INTEL_debug_module)
4444
EXT(SPV_INTEL_runtime_aligned)
45+
EXT(SPV_INTEL_arithmetic_fence)

lib/SPIRV/SPIRVReader.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,6 +2805,15 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
28052805
return mapValue(
28062806
BV, transArbFloatInst(static_cast<SPIRVInstruction *>(BV), BB, true));
28072807

2808+
case OpArithmeticFenceINTEL: {
2809+
IRBuilder<> Builder(BB);
2810+
auto *BC = static_cast<SPIRVUnary *>(BV);
2811+
Type *RetTy = transType(BC->getType());
2812+
Value *Val = transValue(BC->getOperand(0), F, BB);
2813+
return mapValue(
2814+
BV, Builder.CreateIntrinsic(Intrinsic::arithmetic_fence, RetTy, Val));
2815+
}
2816+
28082817
default: {
28092818
auto OC = BV->getOpCode();
28102819
if (isSPIRVCmpInstTransToLLVMInst(static_cast<SPIRVInstruction *>(BV))) {

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,7 @@ bool LLVMToSPIRVBase::isKnownIntrinsic(Intrinsic::ID Id) {
24052405
case Intrinsic::invariant_end:
24062406
case Intrinsic::dbg_label:
24072407
case Intrinsic::trap:
2408+
case Intrinsic::arithmetic_fence:
24082409
return true;
24092410
default:
24102411
// Unknown intrinsics' declarations should always be translated
@@ -3027,6 +3028,16 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
30273028
else
30283029
return transValue(ConstantInt::getFalse(II->getType()), BB, false);
30293030
}
3031+
case Intrinsic::arithmetic_fence: {
3032+
SPIRVType *Ty = transType(II->getType());
3033+
SPIRVValue *Op = transValue(II->getArgOperand(0), BB);
3034+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_arithmetic_fence)) {
3035+
BM->addCapability(CapabilityFPArithmeticFenceINTEL);
3036+
BM->addExtension(ExtensionID::SPV_INTEL_arithmetic_fence);
3037+
return BM->addUnaryInst(OpArithmeticFenceINTEL, Ty, Op, BB);
3038+
}
3039+
return Op;
3040+
}
30303041
default:
30313042
if (BM->isUnknownIntrinsicAllowed(II))
30323043
return BM->addCallInst(

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,7 @@ _SPIRV_OP(Any)
15661566
_SPIRV_OP(All)
15671567
_SPIRV_OP(BitCount)
15681568
_SPIRV_OP(BitReverse)
1569+
_SPIRV_OP(ArithmeticFenceINTEL)
15691570
#undef _SPIRV_OP
15701571

15711572
class SPIRVAccessChainBase : public SPIRVInstTemplateBase {

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
577577
add(internal::CapabilityRuntimeAlignedAttributeINTEL,
578578
"RuntimeAlignedAttributeINTEL");
579579
add(CapabilityMax, "Max");
580+
add(internal::CapabilityFPArithmeticFenceINTEL, "FPArithmeticFenceINTEL");
580581
}
581582
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
582583

lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,3 +537,4 @@ _SPIRV_OP(TypeBufferSurfaceINTEL, 6086)
537537
_SPIRV_OP(TypeStructContinuedINTEL, 6090)
538538
_SPIRV_OP(ConstantCompositeContinuedINTEL, 6091)
539539
_SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092)
540+
_SPIRV_OP(ArithmeticFenceINTEL, 6144)

lib/SPIRV/libSPIRV/spirv.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ enum Capability {
10511051
CapabilityLongConstantCompositeINTEL = 6089,
10521052
CapabilityAtomicFloat16AddEXT = 6095,
10531053
CapabilityDebugInfoModuleINTEL = 6114,
1054+
CapabilityFPArithmeticFenceINTEL = 6144,
10541055
CapabilityMax = 0x7fffffff,
10551056
};
10561057

@@ -1793,6 +1794,7 @@ enum Op {
17931794
OpTypeStructContinuedINTEL = 6090,
17941795
OpConstantCompositeContinuedINTEL = 6091,
17951796
OpSpecConstantCompositeContinuedINTEL = 6092,
1797+
OpArithmeticFenceINTEL = 6145,
17961798
OpMax = 0x7fffffff,
17971799
};
17981800

lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ enum InternalCapability {
6262
ICapFastCompositeINTEL = 6093,
6363
ICapOptNoneINTEL = 6094,
6464
ICapTokenTypeINTEL = 6112,
65+
ICapFPArithmeticFenceINTEL = 6144
6566
};
6667

6768
enum InternalFunctionControlMask { IFunctionControlOptNoneINTELMask = 0x10000 };
@@ -114,6 +115,8 @@ constexpr Capability CapabilityTokenTypeINTEL =
114115
static_cast<Capability>(ICapTokenTypeINTEL);
115116
constexpr Capability CapabilityRuntimeAlignedAttributeINTEL =
116117
static_cast<Capability>(ICapRuntimeAlignedAttributeINTEL);
118+
constexpr Capability CapabilityFPArithmeticFenceINTEL =
119+
static_cast<Capability>(ICapFPArithmeticFenceINTEL);
117120

118121
constexpr FunctionControlMask FunctionControlOptNoneINTELMask =
119122
static_cast<FunctionControlMask>(IFunctionControlOptNoneINTELMask);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_arithmetic_fence -o %t.spv
3+
; RUN: llvm-spirv %t.spv --to-text -o %t.spt
4+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
5+
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
8+
9+
; RUN: llvm-spirv %t.bc -o %t.negative.spv
10+
; RUN: llvm-spirv %t.negative.spv --to-text -o %t.negative.spt
11+
; RUN: FileCheck < %t.negative.spt %s --check-prefix=CHECK-SPIRV-NEG
12+
13+
; RUN: llvm-spirv -r %t.negative.spv -o %t.negative.rev.bc
14+
; RUN: llvm-dis < %t.negative.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM-NEG
15+
16+
; CHECK-SPIRV: Capability FPArithmeticFenceINTEL
17+
; CHECK-SPIRV: Extension "SPV_INTEL_arithmetic_fence"
18+
; CHECK-SPIRV: Name [[#Res:]] "t"
19+
; CHECK-SPIRV: TypeFloat [[#ResTy:]] 64
20+
; CHECK-SPIRV: FAdd [[#ResTy]] [[#Target:]]
21+
; CHECK-SPIRV: ArithmeticFenceINTEL [[#ResTy]] [[#Res]] [[#Target]]
22+
23+
; CHECK-LLVM: [[#Op:]] = fadd fast double %a, %a
24+
; CHECK-LLVM: %t = call double @llvm.arithmetic.fence.f64(double %[[#Op]])
25+
; CHECK-LLVM: declare double @llvm.arithmetic.fence.f64(double)
26+
27+
; CHECK-SPIRV-NEG-NOT: Capability FPArithmeticFenceINTEL
28+
; CHECK-SPIRV-NEG-NOT: Extension "SPV_INTEL_arithmetic_fence"
29+
; CHECK-SPIRV-NEG-NOT: ArithmeticFenceINTEL
30+
31+
; CHECK-LLVM-NEG-NOT: declare double @llvm.arithmetic.fence.f64(double)
32+
33+
target triple = "spir64-unknown-unknown"
34+
35+
define double @f1(double %a) {
36+
%1 = fadd fast double %a, %a
37+
%t = call double @llvm.arithmetic.fence.f64(double %1)
38+
%2 = fadd fast double %a, %a
39+
%3 = fadd fast double %t, %2
40+
ret double %3
41+
}
42+
43+
declare double @llvm.arithmetic.fence.f64(double)

0 commit comments

Comments
 (0)