https://github.com/MacDue updated 
https://github.com/llvm/llvm-project/pull/126750

>From eee5bc815c4b6b7e5a18503959b2a2354d73058b Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxw...@arm.com>
Date: Tue, 11 Feb 2025 15:32:23 +0000
Subject: [PATCH 1/4] [clang] Lower modf builtin using `llvm.modf` intrinsic

This updates the existing `modf[f|l]` builtin to be lowered via the
`llvm.modf.*` intrinsic when `-fno-math-errno` is set (rather than
directly to a library call).
---
 clang/lib/CodeGen/CGBuiltin.cpp          | 26 ++++++++++++++++++++++++
 clang/test/CodeGen/X86/math-builtins.c   | 26 ++++++++++++++++++++----
 clang/test/CodeGen/aix-builtin-mapping.c |  2 +-
 clang/test/CodeGen/builtin-attributes.c  |  2 +-
 clang/test/CodeGen/math-libcalls.c       | 12 +++++------
 5 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..07522a62ccae6 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -859,6 +859,24 @@ static void emitSincosBuiltin(CodeGenFunction &CGF, const 
CallExpr *E,
   StoreCos->setMetadata(LLVMContext::MD_noalias, AliasScopeList);
 }
 
+static llvm::Value *emitModfBuiltin(CodeGenFunction &CGF, const CallExpr *E,
+                                    llvm::Intrinsic::ID IntrinsicID) {
+  llvm::Value *Val = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *IntPartDest = CGF.EmitScalarExpr(E->getArg(1));
+
+  llvm::Function *F = CGF.CGM.getIntrinsic(IntrinsicID, {Val->getType()});
+  llvm::Value *Call = CGF.Builder.CreateCall(F, Val);
+
+  llvm::Value *FractionalResult = CGF.Builder.CreateExtractValue(Call, 0);
+  llvm::Value *IntegralResult = CGF.Builder.CreateExtractValue(Call, 1);
+
+  QualType DestPtrType = E->getArg(1)->getType()->getPointeeType();
+  LValue IntegralLV = CGF.MakeNaturalAlignAddrLValue(IntPartDest, DestPtrType);
+  CGF.Builder.CreateStore(IntegralResult, IntegralLV.getAddress());
+
+  return FractionalResult;
+}
+
 /// EmitFAbs - Emit a call to @llvm.fabs().
 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
   Function *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
@@ -3259,6 +3277,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
       return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod"));
     }
 
+    case Builtin::BImodf:
+    case Builtin::BImodff:
+    case Builtin::BImodfl:
+    case Builtin::BI__builtin_modf:
+    case Builtin::BI__builtin_modff:
+    case Builtin::BI__builtin_modfl:
+      return RValue::get(emitModfBuiltin(*this, E, Intrinsic::modf));
+
     case Builtin::BIlog:
     case Builtin::BIlogf:
     case Builtin::BIlogl:
diff --git a/clang/test/CodeGen/X86/math-builtins.c 
b/clang/test/CodeGen/X86/math-builtins.c
index d7bf7d57fba26..08c7765dd4002 100644
--- a/clang/test/CodeGen/X86/math-builtins.c
+++ b/clang/test/CodeGen/X86/math-builtins.c
@@ -38,6 +38,24 @@ void foo(double *d, float f, float *fp, long double *l, int 
*i, const char *c) {
 // NO__ERRNO-NEXT: [[FREXP_F128_0:%.+]] = extractvalue { fp128, i32 } 
[[FREXP_F128]], 0
 
 
+// NO__ERRNO: [[MODF_F64:%.+]] = call { double, double } @llvm.modf.f64(double 
%{{.+}})
+// NO__ERRNO-NEXT: [[MODF_F64_FP:%.+]] = extractvalue { double, double } 
[[MODF_F64]], 0
+// NO__ERRNO-NEXT: [[MODF_F64_IP:%.+]] = extractvalue { double, double } 
[[MODF_F64]], 1
+// NO__ERRNO-NEXT: store double [[MODF_F64_IP]], ptr %{{.+}}, align 8
+
+// NO__ERRNO: [[MODF_F32:%.+]] = call { float, float } @llvm.modf.f32(float 
%{{.+}})
+// NO__ERRNO-NEXT: [[MODF_F32_FP:%.+]] = extractvalue { float, float } 
[[MODF_F32]], 0
+// NO__ERRNO-NEXT: [[MODF_F32_IP:%.+]] = extractvalue { float, float } 
[[MODF_F32]], 1
+// NO__ERRNO-NEXT: store float [[MODF_F32_IP]], ptr %{{.+}}, align 4
+
+// NO__ERRNO: [[MODF_F80:%.+]] = call { x86_fp80, x86_fp80 } 
@llvm.modf.f80(x86_fp80 %{{.+}})
+// NO__ERRNO-NEXT: [[MODF_F80_FP:%.+]] = extractvalue { x86_fp80, x86_fp80 } 
[[MODF_F80]], 0
+// NO__ERRNO-NEXT: [[MODF_F80_IP:%.+]] = extractvalue { x86_fp80, x86_fp80 } 
[[MODF_F80]], 1
+// NO__ERRNO-NEXT: store x86_fp80 [[MODF_F80_IP]], ptr %{{.+}}, align 16
+
+// NO__ERRNO: call fp128 @modff128(fp128 noundef %{{.+}}, ptr noundef %{{.+}})
+
+
 // NO__ERRNO: [[SINCOS_F64:%.+]] = call { double, double } 
@llvm.sincos.f64(double %{{.+}})
 // NO__ERRNO-NEXT: [[SINCOS_F64_0:%.+]] = extractvalue { double, double } 
[[SINCOS_F64]], 0
 // NO__ERRNO-NEXT: [[SINCOS_F64_1:%.+]] = extractvalue { double, double } 
[[SINCOS_F64]], 1
@@ -139,10 +157,10 @@ void foo(double *d, float f, float *fp, long double *l, 
int *i, const char *c) {
 
   __builtin_modf(f,d);       __builtin_modff(f,fp);      __builtin_modfl(f,l); 
__builtin_modff128(f,l);
 
-// NO__ERRNO: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE:#[0-9]+]]
-// NO__ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
-// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
-// NO__ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) 
[[NOT_READNONE]]
+// NO__ERRNO: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
+// NO__ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
+// NO__ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) 
[[NOT_READNONE:#[0-9]+]]
 // HAS_ERRNO: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
 // HAS_ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
 // HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
diff --git a/clang/test/CodeGen/aix-builtin-mapping.c 
b/clang/test/CodeGen/aix-builtin-mapping.c
index a79218c6f1d8b..cc1cc1a44f32c 100644
--- a/clang/test/CodeGen/aix-builtin-mapping.c
+++ b/clang/test/CodeGen/aix-builtin-mapping.c
@@ -17,6 +17,6 @@ int main()
   returnValue = __builtin_ldexpl(1.0L, 1);
 }
 
-// CHECK: %call = call double @modf(double noundef 1.000000e+00, ptr noundef 
%DummyLongDouble) #3
+// CHECK: %{{.+}} = call { double, double } @llvm.modf.f64(double 1.000000e+00)
 // CHECK: %{{.+}} = call { double, i32 } @llvm.frexp.f64.i32(double 
0.000000e+00)
 // CHECK: %{{.+}} = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 1)
diff --git a/clang/test/CodeGen/builtin-attributes.c 
b/clang/test/CodeGen/builtin-attributes.c
index e5b0faccfd23f..8461467b10469 100644
--- a/clang/test/CodeGen/builtin-attributes.c
+++ b/clang/test/CodeGen/builtin-attributes.c
@@ -1,5 +1,5 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -fmath-errno -emit-llvm 
-o - %s | FileCheck %s
 
 int printf(const char *, ...);
 void exit(int);
diff --git a/clang/test/CodeGen/math-libcalls.c 
b/clang/test/CodeGen/math-libcalls.c
index bcc61c8f046b4..507d3a9bd0369 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -83,15 +83,15 @@ void foo(double *d, float f, float *fp, long double *l, int 
*i, const char *c) {
 
   modf(f,d);       modff(f,fp);      modfl(f,l);
 
-  // NO__ERRNO: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
-  // NO__ERRNO: declare float @modff(float noundef, ptr noundef) 
[[NOT_READNONE]]
-  // NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
+  // NO__ERRNO: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
+  // NO__ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
+  // NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
   // HAS_ERRNO: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
   // HAS_ERRNO: declare float @modff(float noundef, ptr noundef) 
[[NOT_READNONE]]
   // HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
-  // HAS_MAYTRAP: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
-  // HAS_MAYTRAP: declare float @modff(float noundef, ptr noundef) 
[[NOT_READNONE]]
-  // HAS_MAYTRAP: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
+  // HAS_MAYTRAP: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
+  // HAS_MAYTRAP: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
+  // HAS_MAYTRAP: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
 
   nan(c);        nanf(c);       nanl(c);
 

>From 0121d99af4d121242becc05941c939cad84105d4 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxw...@arm.com>
Date: Tue, 11 Feb 2025 17:53:00 +0000
Subject: [PATCH 2/4] Fixups

---
 clang/lib/CodeGen/CGBuiltin.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 07522a62ccae6..853b236bcb0df 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -864,8 +864,8 @@ static llvm::Value *emitModfBuiltin(CodeGenFunction &CGF, 
const CallExpr *E,
   llvm::Value *Val = CGF.EmitScalarExpr(E->getArg(0));
   llvm::Value *IntPartDest = CGF.EmitScalarExpr(E->getArg(1));
 
-  llvm::Function *F = CGF.CGM.getIntrinsic(IntrinsicID, {Val->getType()});
-  llvm::Value *Call = CGF.Builder.CreateCall(F, Val);
+  llvm::Value *Call =
+      CGF.Builder.CreateIntrinsic(IntrinsicID, {Val->getType()}, Val);
 
   llvm::Value *FractionalResult = CGF.Builder.CreateExtractValue(Call, 0);
   llvm::Value *IntegralResult = CGF.Builder.CreateExtractValue(Call, 1);

>From 0c5a3a629b94dbe726dfc65c879d37ab9b6b13a3 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxw...@arm.com>
Date: Wed, 12 Feb 2025 13:26:13 +0000
Subject: [PATCH 3/4] Fixups

---
 clang/lib/CodeGen/CGBuiltin.cpp         | 17 ++++++++---------
 clang/test/CodeGen/X86/math-builtins.c  |  6 +++---
 clang/test/CodeGen/builtin-attributes.c | 13 +++++++++----
 clang/test/CodeGen/math-builtins-long.c |  6 +++---
 clang/test/CodeGen/math-libcalls.c      |  6 +++---
 5 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 853b236bcb0df..8dc6b3c4b9b53 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -872,7 +872,7 @@ static llvm::Value *emitModfBuiltin(CodeGenFunction &CGF, 
const CallExpr *E,
 
   QualType DestPtrType = E->getArg(1)->getType()->getPointeeType();
   LValue IntegralLV = CGF.MakeNaturalAlignAddrLValue(IntPartDest, DestPtrType);
-  CGF.Builder.CreateStore(IntegralResult, IntegralLV.getAddress());
+  CGF.EmitStoreOfScalar(IntegralResult, IntegralLV);
 
   return FractionalResult;
 }
@@ -3277,14 +3277,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
       return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod"));
     }
 
-    case Builtin::BImodf:
-    case Builtin::BImodff:
-    case Builtin::BImodfl:
-    case Builtin::BI__builtin_modf:
-    case Builtin::BI__builtin_modff:
-    case Builtin::BI__builtin_modfl:
-      return RValue::get(emitModfBuiltin(*this, E, Intrinsic::modf));
-
     case Builtin::BIlog:
     case Builtin::BIlogf:
     case Builtin::BIlogl:
@@ -4122,6 +4114,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_frexpf128:
   case Builtin::BI__builtin_frexpf16:
     return RValue::get(emitFrexpBuiltin(*this, E, Intrinsic::frexp));
+  case Builtin::BImodf:
+  case Builtin::BImodff:
+  case Builtin::BImodfl:
+  case Builtin::BI__builtin_modf:
+  case Builtin::BI__builtin_modff:
+  case Builtin::BI__builtin_modfl:
+    return RValue::get(emitModfBuiltin(*this, E, Intrinsic::modf));
   case Builtin::BI__builtin_isgreater:
   case Builtin::BI__builtin_isgreaterequal:
   case Builtin::BI__builtin_isless:
diff --git a/clang/test/CodeGen/X86/math-builtins.c 
b/clang/test/CodeGen/X86/math-builtins.c
index 08c7765dd4002..d5301b7bafd9c 100644
--- a/clang/test/CodeGen/X86/math-builtins.c
+++ b/clang/test/CodeGen/X86/math-builtins.c
@@ -161,9 +161,9 @@ void foo(double *d, float f, float *fp, long double *l, int 
*i, const char *c) {
 // NO__ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
 // NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
 // NO__ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) 
[[NOT_READNONE:#[0-9]+]]
-// HAS_ERRNO: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
-// HAS_ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
-// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) 
[[NOT_READNONE]]
 
   __builtin_nan(c);        __builtin_nanf(c);       __builtin_nanl(c); 
__builtin_nanf128(c);
diff --git a/clang/test/CodeGen/builtin-attributes.c 
b/clang/test/CodeGen/builtin-attributes.c
index 8461467b10469..506b165fcf36e 100644
--- a/clang/test/CodeGen/builtin-attributes.c
+++ b/clang/test/CodeGen/builtin-attributes.c
@@ -1,5 +1,5 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -fmath-errno -emit-llvm 
-o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -emit-llvm -o - %s | 
FileCheck %s
 
 int printf(const char *, ...);
 void exit(int);
@@ -24,6 +24,11 @@ char* f2(char* a, char* b) {
   return __builtin_strstr(a, b);
 }
 
+// Note: Use asm label to disable intrinsic lowering of modf.
+double modf(double x, double*) asm("modf");
+float modff(float x, float*) asm("modff");
+long double modfl(long double x, long double*) asm("modfl");
+
 // frexp is NOT readnone. It writes to its pointer argument.
 //
 // CHECK: f3
@@ -55,9 +60,9 @@ int f3(double x) {
   frexp(x, &e);
   frexpf(x, &e);
   frexpl(x, &e);
-  __builtin_modf(x, &e);
-  __builtin_modff(x, &e);
-  __builtin_modfl(x, &e);
+  modf(x, &e);
+  modff(x, &e);
+  modfl(x, &e);
   __builtin_remquo(x, x, &e);
   __builtin_remquof(x, x, &e);
   __builtin_remquol(x, x, &e);
diff --git a/clang/test/CodeGen/math-builtins-long.c 
b/clang/test/CodeGen/math-builtins-long.c
index 183349e0f0173..87e64a2eaa1c3 100644
--- a/clang/test/CodeGen/math-builtins-long.c
+++ b/clang/test/CodeGen/math-builtins-long.c
@@ -58,9 +58,9 @@ void foo(long double f, long double *l, int *i, const char 
*c) {
   // PPCF128: call fp128 @ldexpf128(fp128 noundef %{{.+}}, {{(signext)?.+}})
   __builtin_ldexpl(f,f);
 
-  // F80: call x86_fp80 @modfl(x86_fp80 noundef %{{.+}}, ptr noundef %{{.+}})
-  // PPC: call ppc_fp128 @modfl(ppc_fp128 noundef %{{.+}}, ptr noundef %{{.+}})
-  // X86F128: call fp128 @modfl(fp128 noundef %{{.+}}, ptr noundef %{{.+}})
+  // F80: call { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80 %{{.+}})
+  // PPC: call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %{{.+}})
+  // X86F128: call { fp128, fp128 } @llvm.modf.f128(fp128 %{{.+}})
   // PPCF128: call fp128 @modff128(fp128 noundef %{{.+}}, ptr noundef %{{.+}})
   __builtin_modfl(f,l);
 
diff --git a/clang/test/CodeGen/math-libcalls.c 
b/clang/test/CodeGen/math-libcalls.c
index 507d3a9bd0369..a5c8ae5c4c07c 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -86,9 +86,9 @@ void foo(double *d, float f, float *fp, long double *l, int 
*i, const char *c) {
   // NO__ERRNO: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
   // NO__ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
   // NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
-  // HAS_ERRNO: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
-  // HAS_ERRNO: declare float @modff(float noundef, ptr noundef) 
[[NOT_READNONE]]
-  // HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
+  // HAS_ERRNO: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
+  // HAS_ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
+  // HAS_ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
   // HAS_MAYTRAP: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
   // HAS_MAYTRAP: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
   // HAS_MAYTRAP: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]

>From 7b1f5cc7c5885a6e5ef10cbef45b1d67b4872793 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxw...@arm.com>
Date: Mon, 17 Feb 2025 11:57:58 +0000
Subject: [PATCH 4/4] Don't use intrinsic in constrained mode

---
 clang/lib/CodeGen/CGBuiltin.cpp    | 2 ++
 clang/test/CodeGen/math-libcalls.c | 6 +++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8dc6b3c4b9b53..063775f5d8a51 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4120,6 +4120,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_modf:
   case Builtin::BI__builtin_modff:
   case Builtin::BI__builtin_modfl:
+    if (Builder.getIsFPConstrained())
+      break;
     return RValue::get(emitModfBuiltin(*this, E, Intrinsic::modf));
   case Builtin::BI__builtin_isgreater:
   case Builtin::BI__builtin_isgreaterequal:
diff --git a/clang/test/CodeGen/math-libcalls.c 
b/clang/test/CodeGen/math-libcalls.c
index a5c8ae5c4c07c..2d936b73ca99d 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -89,9 +89,9 @@ void foo(double *d, float f, float *fp, long double *l, int 
*i, const char *c) {
   // HAS_ERRNO: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
   // HAS_ERRNO: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
   // HAS_ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
-  // HAS_MAYTRAP: declare { double, double } @llvm.modf.f64(double) 
[[READNONE_INTRINSIC]]
-  // HAS_MAYTRAP: declare { float, float } @llvm.modf.f32(float) 
[[READNONE_INTRINSIC]]
-  // HAS_MAYTRAP: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) 
[[READNONE_INTRINSIC]]
+  // HAS_MAYTRAP: declare double @modf(double noundef, ptr noundef) 
[[NOT_READNONE]]
+  // HAS_MAYTRAP: declare float @modff(float noundef, ptr noundef) 
[[NOT_READNONE]]
+  // HAS_MAYTRAP: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) 
[[NOT_READNONE]]
 
   nan(c);        nanf(c);       nanl(c);
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to