@@ -2032,12 +2032,33 @@ void addIntelFPGADecorationsForStructMember(SPIRVEntry *E,
2032
2032
bool LLVMToSPIRV::isKnownIntrinsic (Intrinsic::ID Id) {
2033
2033
// Known intrinsics usually do not need translation of their declaration
2034
2034
switch (Id) {
2035
+ case Intrinsic::abs :
2035
2036
case Intrinsic::assume:
2036
2037
case Intrinsic::bitreverse:
2037
- case Intrinsic::sqrt :
2038
- case Intrinsic::fabs :
2039
- case Intrinsic::abs :
2040
2038
case Intrinsic::ceil :
2039
+ case Intrinsic::copysign :
2040
+ case Intrinsic::cos :
2041
+ case Intrinsic::exp :
2042
+ case Intrinsic::exp2 :
2043
+ case Intrinsic::fabs :
2044
+ case Intrinsic::floor :
2045
+ case Intrinsic::fma :
2046
+ case Intrinsic::log :
2047
+ case Intrinsic::log10 :
2048
+ case Intrinsic::log2 :
2049
+ case Intrinsic::maximum:
2050
+ case Intrinsic::maxnum:
2051
+ case Intrinsic::minimum:
2052
+ case Intrinsic::minnum:
2053
+ case Intrinsic::nearbyint :
2054
+ case Intrinsic::pow :
2055
+ case Intrinsic::powi:
2056
+ case Intrinsic::rint :
2057
+ case Intrinsic::round :
2058
+ case Intrinsic::roundeven:
2059
+ case Intrinsic::sin :
2060
+ case Intrinsic::sqrt :
2061
+ case Intrinsic::trunc :
2041
2062
case Intrinsic::ctpop:
2042
2063
case Intrinsic::ctlz:
2043
2064
case Intrinsic::cttz:
@@ -2060,7 +2081,6 @@ bool LLVMToSPIRV::isKnownIntrinsic(Intrinsic::ID Id) {
2060
2081
case Intrinsic::fmuladd:
2061
2082
case Intrinsic::memset :
2062
2083
case Intrinsic::memcpy :
2063
- case Intrinsic::nearbyint :
2064
2084
case Intrinsic::lifetime_start:
2065
2085
case Intrinsic::lifetime_end:
2066
2086
case Intrinsic::dbg_declare:
@@ -2097,6 +2117,45 @@ LLVMToSPIRV::applyRoundingModeConstraint(Value *V, SPIRVInstruction *I) {
2097
2117
return I;
2098
2118
}
2099
2119
2120
+ static SPIRVWord getBuiltinIdForIntrinsic (Intrinsic::ID IID) {
2121
+ switch (IID) {
2122
+ // Note: In some cases the semantics of the OpenCL builtin are not identical
2123
+ // to the semantics of the corresponding LLVM IR intrinsic. The LLVM
2124
+ // intrinsics handled here assume the default floating point environment
2125
+ // (no unmasked exceptions, round-to-nearest-ties-even rounding mode)
2126
+ // and assume that the operations have no side effects (FP status flags
2127
+ // aren't maintained), so the OpenCL builtin behavior should be
2128
+ // acceptable.
2129
+ case Intrinsic::ceil : return OpenCLLIB::Ceil;
2130
+ case Intrinsic::copysign : return OpenCLLIB::Copysign;
2131
+ case Intrinsic::cos : return OpenCLLIB::Cos;
2132
+ case Intrinsic::exp : return OpenCLLIB::Exp;
2133
+ case Intrinsic::exp2 : return OpenCLLIB::Exp2;
2134
+ case Intrinsic::fabs : return OpenCLLIB::Fabs;
2135
+ case Intrinsic::floor : return OpenCLLIB::Floor;
2136
+ case Intrinsic::fma : return OpenCLLIB::Fma;
2137
+ case Intrinsic::log : return OpenCLLIB::Log;
2138
+ case Intrinsic::log10 : return OpenCLLIB::Log10;
2139
+ case Intrinsic::log2 : return OpenCLLIB::Log2;
2140
+ case Intrinsic::maximum: return OpenCLLIB::Fmax;
2141
+ case Intrinsic::maxnum: return OpenCLLIB::Fmax;
2142
+ case Intrinsic::minimum: return OpenCLLIB::Fmin;
2143
+ case Intrinsic::minnum: return OpenCLLIB::Fmin;
2144
+ case Intrinsic::nearbyint : return OpenCLLIB::Rint;
2145
+ case Intrinsic::pow : return OpenCLLIB::Pow;
2146
+ case Intrinsic::powi: return OpenCLLIB::Pown;
2147
+ case Intrinsic::rint : return OpenCLLIB::Rint;
2148
+ case Intrinsic::round : return OpenCLLIB::Round;
2149
+ case Intrinsic::roundeven: return OpenCLLIB::Rint;
2150
+ case Intrinsic::sin : return OpenCLLIB::Sin;
2151
+ case Intrinsic::sqrt : return OpenCLLIB::Sqrt;
2152
+ case Intrinsic::trunc : return OpenCLLIB::Trunc;
2153
+ default :
2154
+ assert (false && " Builtin ID requested for Unhandled intrinsic!" );
2155
+ return 0 ;
2156
+ }
2157
+ }
2158
+
2100
2159
SPIRVValue *LLVMToSPIRV::transIntrinsicInst (IntrinsicInst *II,
2101
2160
SPIRVBasicBlock *BB) {
2102
2161
auto GetMemoryAccess = [](MemIntrinsic *MI) -> std::vector<SPIRVWord> {
@@ -2139,35 +2198,65 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
2139
2198
SPIRVValue *Op = transValue (II->getArgOperand (0 ), BB);
2140
2199
return BM->addUnaryInst (OpBitReverse, Ty, Op, BB);
2141
2200
}
2142
- case Intrinsic::sqrt : {
2143
- return BM->addExtInst (transType (II->getType ()),
2144
- BM->getExtInstSetId (SPIRVEIS_OpenCL), OpenCLLIB::Sqrt,
2145
- {transValue (II->getOperand (0 ), BB)}, BB);
2146
- }
2147
- case Intrinsic::fabs : {
2201
+ // Unary FP intrinsic
2202
+ case Intrinsic::ceil :
2203
+ case Intrinsic::cos :
2204
+ case Intrinsic::exp :
2205
+ case Intrinsic::exp2 :
2206
+ case Intrinsic::fabs :
2207
+ case Intrinsic::floor :
2208
+ case Intrinsic::log :
2209
+ case Intrinsic::log10 :
2210
+ case Intrinsic::log2 :
2211
+ case Intrinsic::nearbyint :
2212
+ case Intrinsic::rint :
2213
+ case Intrinsic::round :
2214
+ case Intrinsic::roundeven:
2215
+ case Intrinsic::sin :
2216
+ case Intrinsic::sqrt :
2217
+ case Intrinsic::trunc : {
2148
2218
if (!checkTypeForSPIRVExtendedInstLowering (II, BM))
2149
2219
break ;
2150
- SPIRVWord ExtOp = OpenCLLIB::Fabs ;
2220
+ SPIRVWord ExtOp = getBuiltinIdForIntrinsic (II-> getIntrinsicID ()) ;
2151
2221
SPIRVType *STy = transType (II->getType ());
2152
2222
std::vector<SPIRVValue *> Ops (1 , transValue (II->getArgOperand (0 ), BB));
2153
2223
return BM->addExtInst (STy, BM->getExtInstSetId (SPIRVEIS_OpenCL), ExtOp, Ops,
2154
2224
BB);
2155
2225
}
2156
- case Intrinsic::abs : {
2226
+ // Binary FP intrinsics
2227
+ case Intrinsic::copysign :
2228
+ case Intrinsic::pow :
2229
+ case Intrinsic::powi:
2230
+ case Intrinsic::maximum:
2231
+ case Intrinsic::maxnum:
2232
+ case Intrinsic::minimum:
2233
+ case Intrinsic::minnum: {
2157
2234
if (!checkTypeForSPIRVExtendedInstLowering (II, BM))
2158
2235
break ;
2159
- // LLVM has only one version of abs and it is only for signed integers. We
2160
- // unconditionally choose SAbs here
2161
- SPIRVWord ExtOp = OpenCLLIB::SAbs;
2236
+ SPIRVWord ExtOp = getBuiltinIdForIntrinsic (II->getIntrinsicID ());
2162
2237
SPIRVType *STy = transType (II->getType ());
2163
- std::vector<SPIRVValue *> Ops (1 , transValue (II->getArgOperand (0 ), BB));
2238
+ std::vector<SPIRVValue *> Ops{transValue (II->getArgOperand (0 ), BB),
2239
+ transValue (II->getArgOperand (1 ), BB)};
2240
+ return BM->addExtInst (STy, BM->getExtInstSetId (SPIRVEIS_OpenCL), ExtOp, Ops,
2241
+ BB);
2242
+ }
2243
+ case Intrinsic::fma : {
2244
+ if (!checkTypeForSPIRVExtendedInstLowering (II, BM))
2245
+ break ;
2246
+ SPIRVWord ExtOp = OpenCLLIB::Fma;
2247
+ SPIRVType *STy = transType (II->getType ());
2248
+ std::vector<SPIRVValue *> Ops{transValue (II->getArgOperand (0 ), BB),
2249
+ transValue (II->getArgOperand (1 ), BB),
2250
+ transValue (II->getArgOperand (2 ), BB)};
2164
2251
return BM->addExtInst (STy, BM->getExtInstSetId (SPIRVEIS_OpenCL), ExtOp, Ops,
2165
2252
BB);
2166
2253
}
2167
- case Intrinsic::ceil : {
2254
+ case Intrinsic::abs : {
2168
2255
if (!checkTypeForSPIRVExtendedInstLowering (II, BM))
2169
2256
break ;
2170
- SPIRVWord ExtOp = OpenCLLIB::Ceil;
2257
+ // LLVM has only one version of abs and it is only for signed integers. We
2258
+ // unconditionally choose SAbs here
2259
+ SPIRVWord ExtOp = OpenCLLIB::SAbs;
2171
2260
SPIRVType *STy = transType (II->getType ());
2172
2261
std::vector<SPIRVValue *> Ops (1 , transValue (II->getArgOperand (0 ), BB));
2173
2262
return BM->addExtInst (STy, BM->getExtInstSetId (SPIRVEIS_OpenCL), ExtOp, Ops,
@@ -2309,16 +2398,6 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
2309
2398
return BM->addBinaryInst (OpFAdd, Ty, Mul,
2310
2399
transValue (II->getArgOperand (2 ), BB), BB);
2311
2400
}
2312
- case Intrinsic::maxnum: {
2313
- if (!checkTypeForSPIRVExtendedInstLowering (II, BM))
2314
- break ;
2315
- SPIRVWord ExtOp = OpenCLLIB::Fmax;
2316
- SPIRVType *STy = transType (II->getType ());
2317
- std::vector<SPIRVValue *> Ops{transValue (II->getArgOperand (0 ), BB),
2318
- transValue (II->getArgOperand (1 ), BB)};
2319
- return BM->addExtInst (STy, BM->getExtInstSetId (SPIRVEIS_OpenCL), ExtOp, Ops,
2320
- BB);
2321
- }
2322
2401
case Intrinsic::usub_sat: {
2323
2402
// usub.sat(a, b) -> (a > b) ? a - b : 0
2324
2403
SPIRVType *Ty = transType (II->getType ());
@@ -2391,13 +2470,6 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
2391
2470
Size = 0 ;
2392
2471
return BM->addLifetimeInst (OC, transValue (II->getOperand (1 ), BB), Size , BB);
2393
2472
}
2394
- case Intrinsic::nearbyint : {
2395
- if (!checkTypeForSPIRVExtendedInstLowering (II, BM))
2396
- break ;
2397
- return BM->addExtInst (transType (II->getType ()),
2398
- BM->getExtInstSetId (SPIRVEIS_OpenCL), OpenCLLIB::Rint,
2399
- {transValue (II->getOperand (0 ), BB)}, BB);
2400
- }
2401
2473
// We don't want to mix translation of regular code and debug info, because
2402
2474
// it creates a mess, therefore translation of debug intrinsics is
2403
2475
// postponed until LLVMToSPIRVDbgTran::finalizeDebug...() methods.
0 commit comments