@@ -32,7 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
32
#include " common/LLVMWarningsPush.hpp"
33
33
#include " llvm/ADT/StringSwitch.h"
34
34
#include " common/LLVMWarningsPop.hpp"
35
-
35
+ #include " llvm/IR/InstIterator.h"
36
+ #include < set>
36
37
37
38
using namespace llvm ;
38
39
using namespace IGC ;
@@ -116,6 +117,44 @@ void SPIRMetaDataTranslation::WarpFunctionMetadata(Module& M)
116
117
}
117
118
}
118
119
120
+ bool SPIRMetaDataTranslation::isDoubleMathFunctionUsed (Module& M)
121
+ {
122
+ StringRef mathFunctionNamePrefix = " __builtin_spirv_OpenCL_" ;
123
+ std::set<StringRef> mathFunctionNames = {
124
+ " acos" , " acosh" , " acospi" , " asin" , " asinh" , " asinpi" , " atan" , " atan2" ,
125
+ " atanh" , " atanpi" , " cbrt" , " cos" , " cosh" , " cospi" , " erf" , " erfc" ,
126
+ " exp" , " exp10" , " exp2" , " expm1" , " ln" , " log10" , " log1p" , " log2" ,
127
+ " pow" , " pown" , " powr" , " rootn" , " sin" , " sincos" , " sinh" , " sinpi" ,
128
+ " tan" , " tanh" , " tanpi"
129
+ };
130
+
131
+ for (Function& F : M)
132
+ {
133
+ for (inst_iterator i = inst_begin (&F), e = inst_end (&F); i != e; ++i)
134
+ {
135
+ if (auto CI = dyn_cast<CallInst>(&*i)) {
136
+
137
+ if (CI->getType ()->isDoubleTy () ||
138
+ (CI->getType ()->isVectorTy () && CI->getType ()->getVectorElementType ()->isDoubleTy ()))
139
+ {
140
+ StringRef functionName = CI->getCalledFunction ()->getName ();
141
+
142
+ if (functionName.startswith (mathFunctionNamePrefix))
143
+ {
144
+ functionName = functionName.ltrim (mathFunctionNamePrefix);
145
+ functionName = functionName.take_front (functionName.find (" _" , 0 ));
146
+
147
+ if (mathFunctionNames.find (functionName) != mathFunctionNames.end ()) {
148
+ return true ;
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ return false ;
156
+ }
157
+
119
158
bool SPIRMetaDataTranslation::runOnModule (Module& M)
120
159
{
121
160
WarpFunctionMetadata (M);
@@ -358,8 +397,15 @@ bool SPIRMetaDataTranslation::runOnModule(Module& M)
358
397
break ;
359
398
case FAST_RELAXED_MATH:
360
399
case RELAXED_BUILTINS:
361
- modMD->compOpt .FastRelaxedMath = true ;
362
- modMD->compOpt .RelaxedBuiltins = true ;
400
+ // Our implementations of double math built-in functions are precise only
401
+ // if we don't make any fast relaxed math optimizations.
402
+ // If there is any double-type math function call present in a module, we disable fast relaxed math,
403
+ // even if "-cl-fast-relaxed-math" build option is specified by the user.
404
+ if (!isDoubleMathFunctionUsed (M))
405
+ {
406
+ modMD->compOpt .FastRelaxedMath = true ;
407
+ modMD->compOpt .RelaxedBuiltins = true ;
408
+ }
363
409
break ;
364
410
case DASH_G: modMD->compOpt .DashGSpecified = true ;
365
411
break ;
0 commit comments