ac/llvm: add better code for fsign
[mesa.git] / src / amd / llvm / ac_llvm_helper.cpp
index 578521a6f2d6405bd2c471c26a2b8a343a2c8287..184f76a796815e39aad23836842c240cab92b5b4 100644 (file)
 
 #include <cstring>
 
-#include "ac_binary.h"
-#include "ac_llvm_util.h"
-#include "ac_llvm_build.h"
-
-#include "util/macros.h"
-
 #include <llvm-c/Core.h>
 #include <llvm/Target/TargetMachine.h>
 #include <llvm/IR/IRBuilder.h>
 
 #include <llvm/IR/LegacyPassManager.h>
 
+/* DO NOT REORDER THE HEADERS
+ * The LLVM headers need to all be included before any Mesa header,
+ * as they use the `restrict` keyword in ways that are incompatible
+ * with our #define in include/c99_compat.h
+ */
+
+#include "ac_binary.h"
+#include "ac_llvm_util.h"
+#include "ac_llvm_build.h"
+
+#include "util/macros.h"
+
 void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes)
 {
    llvm::Argument *A = llvm::unwrap<llvm::Argument>(val);
    A->addAttr(llvm::Attribute::getWithDereferenceableBytes(A->getContext(), bytes));
 }
 
+void ac_add_attr_alignment(LLVMValueRef val, uint64_t bytes)
+{
+#if LLVM_VERSION_MAJOR >= 10
+       llvm::Argument *A = llvm::unwrap<llvm::Argument>(val);
+       A->addAttr(llvm::Attribute::getWithAlignment(A->getContext(), llvm::Align(bytes)));
+#else
+       /* Avoid unused parameter warnings. */
+       (void)val;
+       (void)bytes;
+#endif
+}
+
 bool ac_is_sgpr_param(LLVMValueRef arg)
 {
        llvm::Argument *A = llvm::unwrap<llvm::Argument>(arg);
@@ -103,6 +121,31 @@ LLVMBuilderRef ac_create_builder(LLVMContextRef ctx,
        return builder;
 }
 
+void ac_enable_signed_zeros(struct ac_llvm_context *ctx)
+{
+       if (ctx->float_mode == AC_FLOAT_MODE_DEFAULT_OPENGL) {
+               auto *b = llvm::unwrap(ctx->builder);
+               llvm::FastMathFlags flags = b->getFastMathFlags();
+
+               /* This disables the optimization of (x + 0), which is used
+                * to convert negative zero to positive zero.
+                */
+               flags.setNoSignedZeros(false);
+               b->setFastMathFlags(flags);
+       }
+}
+
+void ac_disable_signed_zeros(struct ac_llvm_context *ctx)
+{
+       if (ctx->float_mode == AC_FLOAT_MODE_DEFAULT_OPENGL) {
+               auto *b = llvm::unwrap(ctx->builder);
+               llvm::FastMathFlags flags = b->getFastMathFlags();
+
+               flags.setNoSignedZeros();
+               b->setFastMathFlags(flags);
+       }
+}
+
 LLVMTargetLibraryInfoRef
 ac_create_target_library_info(const char *triple)
 {