@@ -32,7 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3232#include " common/LLVMWarningsPush.hpp"
3333#include " llvm/ADT/StringSwitch.h"
3434#include " common/LLVMWarningsPop.hpp"
35-
35+ #include " llvm/IR/InstIterator.h"
36+ #include < set>
3637
3738using namespace llvm ;
3839using namespace IGC ;
@@ -116,6 +117,44 @@ void SPIRMetaDataTranslation::WarpFunctionMetadata(Module& M)
116117 }
117118}
118119
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+
119158bool SPIRMetaDataTranslation::runOnModule (Module& M)
120159{
121160 WarpFunctionMetadata (M);
@@ -358,8 +397,15 @@ bool SPIRMetaDataTranslation::runOnModule(Module& M)
358397 break ;
359398 case FAST_RELAXED_MATH:
360399 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+ }
363409 break ;
364410 case DASH_G: modMD->compOpt .DashGSpecified = true ;
365411 break ;
0 commit comments