This builtin will be converted to llvm.set.rounding intrinsic
in IR level and should be work with "#pragma STDC FENV_ACCESS ON"
since it changes default FP environment. Users can change rounding
mode via this builtin without introducing libc dependency.
Reviewed by: andrew.w.kaylor, rjmccall, sepavloff, aaron.ballman
Differential Revision: https://reviews.llvm.org/
D145765
Signed-off-by: jinge90 <ge.jin@intel.com>
- Add ``__builtin_elementwise_log2`` builtin for floating point types only.
- Add ``__builtin_elementwise_exp`` builtin for floating point types only.
- Add ``__builtin_elementwise_exp2`` builtin for floating point types only.
+- Add ``__builtin_set_flt_rounds`` builtin for X86, x86_64, Arm and AArch64 only.
AST Matchers
------------
// Access to floating point environment
BUILTIN(__builtin_flt_rounds, "i", "n")
+BUILTIN(__builtin_set_flt_rounds, "vi", "n")
// C99 complex builtins
BUILTIN(__builtin_cabs, "dXd", "Fne")
return RValue::get(Result);
}
+ case Builtin::BI__builtin_set_flt_rounds: {
+ Function *F = CGM.getIntrinsic(Intrinsic::set_rounding);
+
+ Value *V = EmitScalarExpr(E->getArg(0));
+ Builder.CreateCall(F, V);
+ return RValue::get(nullptr);
+ }
+
case Builtin::BI__builtin_fpclassify: {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
// FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here.
return ExprError();
break;
+ case Builtin::BI__builtin_set_flt_rounds:
+ if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall,
+ {llvm::Triple::x86, llvm::Triple::x86_64,
+ llvm::Triple::arm, llvm::Triple::thumb,
+ llvm::Triple::aarch64}))
+ return ExprError();
+ break;
+
case Builtin::BI__builtin_isgreater:
case Builtin::BI__builtin_isgreaterequal:
case Builtin::BI__builtin_isless:
--- /dev/null
+// RUN: %clang_cc1 -triple x86_64-gnu-linux %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-gnu-linux %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+void test_builtin_set_flt_rounds() {
+ __builtin_set_flt_rounds(1);
+ // CHECK: call void @llvm.set.rounding(i32 1)
+}
--- /dev/null
+// RUN: %clang_cc1 -triple mipsel-unknown-linux -fsyntax-only %s -verify=expected,unsupported
+// RUN: %clang_cc1 -triple x86_64-gnu-linux -fsyntax-only %s -verify
+struct S {int a;};
+void test_builtin_set_flt_rounds() {
+ __builtin_set_flt_rounds(1); // unsupported-error {{builtin is not supported on this target}}
+ struct S s;
+ __builtin_set_flt_rounds(s); // expected-error {{passing 'struct S' to parameter of incompatible type}}
+}