ac: generate FMA for inexact instructions for radeonsi
[mesa.git] / src / amd / llvm / ac_llvm_helper.cpp
index 578521a6f2d6405bd2c471c26a2b8a343a2c8287..f5383344dd4f3c37348449d0eb28c61dd6d3699d 100644 (file)
@@ -96,6 +96,11 @@ LLVMBuilderRef ac_create_builder(LLVMContextRef ctx,
                 */
                flags.setAllowReciprocal(); /* arcp */
 
+               /* Allow floating-point contraction (e.g. fusing a multiply
+                * followed by an addition into a fused multiply-and-add).
+                */
+               flags.setAllowContract(); /* contract */
+
                llvm::unwrap(builder)->setFastMathFlags(flags);
                break;
        }
@@ -103,6 +108,32 @@ LLVMBuilderRef ac_create_builder(LLVMContextRef ctx,
        return builder;
 }
 
+/* Return the original state of inexact math. */
+bool ac_disable_inexact_math(LLVMBuilderRef builder)
+{
+       auto *b = llvm::unwrap(builder);
+       llvm::FastMathFlags flags = b->getFastMathFlags();
+
+       if (!flags.allowContract())
+               return false;
+
+       flags.setAllowContract(false);
+       b->setFastMathFlags(flags);
+       return true;
+}
+
+void ac_restore_inexact_math(LLVMBuilderRef builder, bool value)
+{
+       auto *b = llvm::unwrap(builder);
+       llvm::FastMathFlags flags = b->getFastMathFlags();
+
+       if (flags.allowContract() == value)
+               return;
+
+       flags.setAllowContract(value);
+       b->setFastMathFlags(flags);
+}
+
 LLVMTargetLibraryInfoRef
 ac_create_target_library_info(const char *triple)
 {