[clang] [Clang] Implement __builtin_fpclassify (PR #190848)
Yeongu Choe via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 7 13:40:39 PDT 2026
https://github.com/YeonguChoe created https://github.com/llvm/llvm-project/pull/190848
### Content
- `__builtin_fpclassify` is a function classify floating point value into one of `FP_NAN`, `FP_INFINITE`, `FP_NORMAL`, `FP_SUBNORMAL` and `FP_ZERO`.
- Applied LLVM IR output to FileCheck test files using `__builtin_fpclassify` function.
### Reference
- https://gcc.gnu.org/onlinedocs/gcc/Floating-Point-Format-Builtins.html#index-_005f_005fbuiltin_005ffpclassify
>From 7e4320f5e120bc32d94572c6cd2e7d1c06942bbd Mon Sep 17 00:00:00 2001
From: YeonguChoe <yeongu.choe at icloud.com>
Date: Tue, 7 Apr 2026 16:31:28 -0400
Subject: [PATCH] [Clang] Implement __builtin_fpclassify
- __builtin_fpclassify is a function classify floating point value into one of FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL and FP_ZERO.
- Applied LLVM IR output to FileCheck test files using __builtin_fpclassify function.
---
clang/lib/CodeGen/CGBuiltin.cpp | 88 +++--
.../CIR/CodeGenBuiltins/builtin-fpclassify.c | 329 +++++-------------
clang/test/CodeGen/builtin-fpclassify.c | 92 +++++
.../test/Headers/nvptx_device_math_macro.cpp | 8 +-
4 files changed, 224 insertions(+), 293 deletions(-)
create mode 100644 clang/test/CodeGen/builtin-fpclassify.c
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4d74d681cd320..b260a36e877b5 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4415,60 +4415,58 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_fpclassify: {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
- // FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here.
+
+ Value *NanLiteral = EmitScalarExpr(E->getArg(0));
+ Value *InfiniteLiteral = EmitScalarExpr(E->getArg(1));
+ Value *NormalLiteral = EmitScalarExpr(E->getArg(2));
+ Value *SubnormalLiteral = EmitScalarExpr(E->getArg(3));
+ Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
Value *V = EmitScalarExpr(E->getArg(5));
- llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
- // Create Result
- BasicBlock *Begin = Builder.GetInsertBlock();
- BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn);
+ BasicBlock *Entry = Builder.GetInsertBlock();
+ BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", CurFn);
+ BasicBlock *NotInfinite =
+ createBasicBlock("fpclassify_not_infinite", CurFn);
+ BasicBlock *NotNormal = createBasicBlock("fpclassify_not_normal", CurFn);
+ BasicBlock *NotSubnormal =
+ createBasicBlock("fpclassify_not_subnormal", CurFn);
+ BasicBlock *End = createBasicBlock("fpclassify_end", CurFn);
+
+ // End Block
Builder.SetInsertPoint(End);
- PHINode *Result =
- Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4,
- "fpclassify_result");
+ PHINode *Result = Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 5,
+ "fpclassify_result");
- // if (V==0) return FP_ZERO
- Builder.SetInsertPoint(Begin);
- Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty),
- "iszero");
- Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
- BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn);
- Builder.CreateCondBr(IsZero, End, NotZero);
- Result->addIncoming(ZeroLiteral, Begin);
-
- // if (V != V) return FP_NAN
- Builder.SetInsertPoint(NotZero);
- Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp");
- Value *NanLiteral = EmitScalarExpr(E->getArg(0));
- BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn);
+ // Entry Block
+ Builder.SetInsertPoint(Entry);
+ Value *IsNan = Builder.createIsFPClass(V, FPClassTest::fcNan);
+ Result->addIncoming(NanLiteral, Entry);
Builder.CreateCondBr(IsNan, End, NotNan);
- Result->addIncoming(NanLiteral, NotZero);
- // if (fabs(V) == infinity) return FP_INFINITY
+ // NotNan Block
Builder.SetInsertPoint(NotNan);
- Value *VAbs = EmitFAbs(*this, V);
- Value *IsInf =
- Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()),
- "isinf");
- Value *InfLiteral = EmitScalarExpr(E->getArg(1));
- BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn);
- Builder.CreateCondBr(IsInf, End, NotInf);
- Result->addIncoming(InfLiteral, NotNan);
-
- // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
- Builder.SetInsertPoint(NotInf);
- APFloat Smallest = APFloat::getSmallestNormalized(
- getContext().getFloatTypeSemantics(E->getArg(5)->getType()));
- Value *IsNormal =
- Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest),
- "isnormal");
- Value *NormalResult =
- Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)),
- EmitScalarExpr(E->getArg(3)));
+ Value *IsInfinite = Builder.createIsFPClass(V, FPClassTest::fcInf);
+ Result->addIncoming(InfiniteLiteral, NotNan);
+ Builder.CreateCondBr(IsInfinite, End, NotInfinite);
+
+ // NotInfinite Block
+ Builder.SetInsertPoint(NotInfinite);
+ Value *IsNormal = Builder.createIsFPClass(V, FPClassTest::fcNormal);
+ Result->addIncoming(NormalLiteral, NotInfinite);
+ Builder.CreateCondBr(IsNormal, End, NotNormal);
+
+ // NotNormal Block
+ Builder.SetInsertPoint(NotNormal);
+ Value *IsSubnormal = Builder.createIsFPClass(V, FPClassTest::fcSubnormal);
+ Result->addIncoming(SubnormalLiteral, NotNormal);
+ Builder.CreateCondBr(IsSubnormal, End, NotSubnormal);
+
+ // NotSubnormal Block
+ Builder.SetInsertPoint(NotSubnormal);
+ Result->addIncoming(ZeroLiteral, NotSubnormal);
Builder.CreateBr(End);
- Result->addIncoming(NormalResult, NotInf);
- // return Result
+ // End Block
Builder.SetInsertPoint(End);
return RValue::get(Result);
}
diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c b/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c
index bad83c4f0ef4c..39e1b35ba7e1b 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c
@@ -29,55 +29,23 @@ void test_fpclassify_nan(){
// CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
// CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else %[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
-// LLVM: %[[VAL:.*]] = load float, ptr
-// LLVM-NEXT: %[[IS_ZERO:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 96)
-// LLVM-NEXT: br i1 %[[IS_ZERO]], label %[[BB_ZERO:.*]], label %[[BB_NOT_ZERO:.*]]
-// LLVM: [[BB_ZERO]]:
-// LLVM-NEXT: br label %[[BB_RET:.*]]
-// LLVM: [[BB_NOT_ZERO]]:
-// LLVM-NEXT: %[[IS_NAN:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 3)
-// LLVM-NEXT: br i1 %[[IS_NAN]], label %[[BB_NAN:.*]], label %[[BB_NOT_NAN:.*]]
-// LLVM: [[BB_NAN]]:
-// LLVM-NEXT: br label %[[BB_MERGE1:.*]]
-// LLVM: [[BB_NOT_NAN]]:
-// LLVM-NEXT: %[[IS_INF:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 516)
-// LLVM-NEXT: br i1 %[[IS_INF]], label %[[BB_INF:.*]], label %[[BB_NOT_INF:.*]]
-// LLVM: [[BB_INF]]:
-// LLVM-NEXT: br label %[[BB_MERGE2:.*]]
-// LLVM: [[BB_NOT_INF]]:
-// LLVM-NEXT: %[[IS_NORMAL:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 264)
-// LLVM-NEXT: %[[NORMAL_OR_SUBNORMAL:.*]] = select i1 %[[IS_NORMAL]], i32 264, i32 144
-// LLVM-NEXT: br label %[[BB_MERGE2]]
-// LLVM: [[BB_MERGE2]]:
-// LLVM-NEXT: %[[PHI_INF_SEL:.*]] = phi i32 [ %[[NORMAL_OR_SUBNORMAL]], %[[BB_NOT_INF]] ], [ 516, %[[BB_INF]] ]
-// LLVM-NEXT: br label %[[BB_CONT1:.*]]
-// LLVM: [[BB_CONT1]]:
-// LLVM-NEXT: br label %[[BB_MERGE1]]
-// LLVM: [[BB_MERGE1]]:
-// LLVM-NEXT: %[[PHI_NAN_SEL:.*]] = phi i32 [ %[[PHI_INF_SEL]], %[[BB_CONT1]] ], [ 3, %[[BB_NAN]] ]
-// LLVM-NEXT: br label %[[BB_CONT2:.*]]
-// LLVM: [[BB_CONT2]]:
-// LLVM-NEXT: br label %[[BB_RET]]
-// LLVM: [[BB_RET]]:
-// LLVM-NEXT: %[[PHI_FINAL:.*]] = phi i32 [ %[[PHI_NAN_SEL]], %[[BB_CONT2]] ], [ 96, %[[BB_ZERO]] ]
-// LLVM-NEXT: br label %[[BB_EXIT:.*]]
-// LLVM: [[BB_EXIT]]:
-
-// OGCG: %[[CMP_ZERO:.+]] = fcmp oeq float %[[VAL:.+]],
-// OGCG-NEXT: br i1 %[[CMP_ZERO]], label %[[BB_RET:.+]], label %[[BB_NOT_ZERO:.+]]
-// OGCG: [[BB_RET]]:
-// OGCG-NEXT: %[[PHI:.+]] = phi i32 [ 96, %[[BB_ENTRY:.+]] ], [ 3, %[[BB_NOT_ZERO]] ], [ 516, %[[BB_NOT_NAN:.+]] ], [ %[[SEL:.+]], %[[BB_NOT_INF:.+]] ]
-// OGCG: [[BB_NOT_ZERO]]:
-// OGCG-NEXT: %[[CMP_NAN:.+]] = fcmp uno float %[[VAL]], %[[VAL]]
-// OGCG-NEXT: br i1 %[[CMP_NAN]], label %[[BB_RET]], label %[[BB_NOT_NAN]]
-// OGCG: [[BB_NOT_NAN]]:
-// OGCG-NEXT: %[[FABS:.+]] = call float @llvm.fabs.f32(float %[[VAL]])
-// OGCG-NEXT: %[[CMP_INF:.+]] = fcmp oeq float %[[FABS]],
-// OGCG-NEXT: br i1 %[[CMP_INF]], label %[[BB_RET]], label %[[BB_NOT_INF]]
-// OGCG: [[BB_NOT_INF]]:
-// OGCG-NEXT: %[[CMP_NORMAL:.+]] = fcmp uge float %[[FABS]],
-// OGCG-NEXT: %[[SEL]] = select i1 %[[CMP_NORMAL]], i32 264, i32 144
-// OGCG-NEXT: br label %[[BB_RET]]
+// LLVM: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS1]]
+// LLVM: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS2]]
+// LLVM: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS3]]
+// LLVM: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: phi i32
+
+// OGCG: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS1]]
+// OGCG: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS2]]
+// OGCG: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS3]]
+// OGCG: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: phi i32
}
void test_fpclassify_inf(){
@@ -98,54 +66,23 @@ void test_fpclassify_inf(){
// CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
// CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else %[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
-// LLVM: %[[VAL:.+]] = load float, ptr
-// LLVM-NEXT: %[[IS_ZERO:.+]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 96)
-// LLVM-NEXT: br i1 %[[IS_ZERO]], label %[[BB_ZERO:.+]], label %[[BB_NOT_ZERO:.+]]
-// LLVM: [[BB_ZERO]]:
-// LLVM-NEXT: br label %[[BB_RET:.+]]
-// LLVM: [[BB_NOT_ZERO]]:
-// LLVM-NEXT: %[[IS_NAN:.+]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 3)
-// LLVM-NEXT: br i1 %[[IS_NAN]], label %[[BB_NAN:.+]], label %[[BB_NOT_NAN:.+]]
-// LLVM: [[BB_NAN]]:
-// LLVM-NEXT: br label %[[BB_MERGE1:.+]]
-// LLVM: [[BB_NOT_NAN]]:
-// LLVM-NEXT: %[[IS_INF:.+]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 516)
-// LLVM-NEXT: br i1 %[[IS_INF]], label %[[BB_INF:.+]], label %[[BB_NOT_INF:.+]]
-// LLVM: [[BB_INF]]:
-// LLVM-NEXT: br label %[[BB_MERGE2:.+]]
-// LLVM: [[BB_NOT_INF]]:
-// LLVM-NEXT: %[[IS_NORMAL:.+]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 264)
-// LLVM-NEXT: %[[SEL:.+]] = select i1 %[[IS_NORMAL]], i32 264, i32 144
-// LLVM-NEXT: br label %[[BB_MERGE2]]
-// LLVM: [[BB_MERGE2]]:
-// LLVM-NEXT: %[[PHI1:.+]] = phi i32 [ %[[SEL]], %[[BB_NOT_INF]] ], [ 516, %[[BB_INF]] ]
-// LLVM-NEXT: br label %[[BB_CONT1:.+]]
-// LLVM: [[BB_CONT1]]:
-// LLVM-NEXT: br label %[[BB_MERGE1]]
-// LLVM: [[BB_MERGE1]]:
-// LLVM-NEXT: %[[PHI2:.+]] = phi i32 [ %[[PHI1]], %[[BB_CONT1]] ], [ 3, %[[BB_NAN]] ]
-// LLVM-NEXT: br label %[[BB_CONT2:.+]]
-// LLVM: [[BB_CONT2]]:
-// LLVM-NEXT: br label %[[BB_RET]]
-// LLVM: [[BB_RET]]:
-// LLVM-NEXT: %[[PHI3:.+]] = phi i32 [ %[[PHI2]], %[[BB_CONT2]] ], [ 96, %[[BB_ZERO]] ]
-// LLVM-NEXT: br label
-
-// OGCG: %[[CMP_ZERO:.+]] = fcmp oeq float %[[VAL:.+]],
-// OGCG-NEXT: br i1 %[[CMP_ZERO]], label %[[BB_RET:.+]], label %[[BB_NOT_ZERO:.+]]
-// OGCG: [[BB_RET]]:
-// OGCG-NEXT: %[[PHI:.+]] = phi i32 [ 96, %[[BB_ENTRY:.+]] ], [ 3, %[[BB_NOT_ZERO]] ], [ 516, %[[BB_NOT_NAN:.+]] ], [ %[[SEL:.+]], %[[BB_NOT_INF:.+]] ]
-// OGCG: [[BB_NOT_ZERO]]:
-// OGCG-NEXT: %[[CMP_NAN:.+]] = fcmp uno float %[[VAL]], %[[VAL]]
-// OGCG-NEXT: br i1 %[[CMP_NAN]], label %[[BB_RET]], label %[[BB_NOT_NAN]]
-// OGCG: [[BB_NOT_NAN]]:
-// OGCG-NEXT: %[[FABS:.+]] = call float @llvm.fabs.f32(float %[[VAL]])
-// OGCG-NEXT: %[[CMP_INF:.+]] = fcmp oeq float %[[FABS]],
-// OGCG-NEXT: br i1 %[[CMP_INF]], label %[[BB_RET]], label %[[BB_NOT_INF]]
-// OGCG: [[BB_NOT_INF]]:
-// OGCG-NEXT: %[[CMP_NORMAL:.+]] = fcmp uge float %[[FABS]],
-// OGCG-NEXT: %[[SEL]] = select i1 %[[CMP_NORMAL]], i32 264, i32 144
-// OGCG-NEXT: br label %[[BB_RET]]
+// LLVM: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS1]]
+// LLVM: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS2]]
+// LLVM: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS3]]
+// LLVM: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: phi i32
+
+// OGCG: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS1]]
+// OGCG: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS2]]
+// OGCG: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS3]]
+// OGCG: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: phi i32
}
void test_fpclassify_normal(){
@@ -166,55 +103,23 @@ void test_fpclassify_normal(){
// CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
// CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else %[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
-// LLVM: %[[VAL:.*]] = load float, ptr
-// LLVM-NEXT: %[[IS_ZERO:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 96)
-// LLVM-NEXT: br i1 %[[IS_ZERO]], label %[[BB_ZERO:.*]], label %[[BB_NOT_ZERO:.*]]
-// LLVM: [[BB_ZERO]]:
-// LLVM-NEXT: br label %[[BB_RET:.*]]
-// LLVM: [[BB_NOT_ZERO]]:
-// LLVM-NEXT: %[[IS_NAN:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 3)
-// LLVM-NEXT: br i1 %[[IS_NAN]], label %[[BB_NAN:.*]], label %[[BB_NOT_NAN:.*]]
-// LLVM: [[BB_NAN]]:
-// LLVM-NEXT: br label %[[BB_MERGE1:.*]]
-// LLVM: [[BB_NOT_NAN]]:
-// LLVM-NEXT: %[[IS_INF:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 516)
-// LLVM-NEXT: br i1 %[[IS_INF]], label %[[BB_INF:.*]], label %[[BB_NOT_INF:.*]]
-// LLVM: [[BB_INF]]:
-// LLVM-NEXT: br label %[[BB_MERGE2:.*]]
-// LLVM: [[BB_NOT_INF]]:
-// LLVM-NEXT: %[[IS_NORMAL:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 264)
-// LLVM-NEXT: %[[NORMAL_OR_SUBNORMAL:.*]] = select i1 %[[IS_NORMAL]], i32 264, i32 144
-// LLVM-NEXT: br label %[[BB_MERGE2]]
-// LLVM: [[BB_MERGE2]]:
-// LLVM-NEXT: %[[PHI_INF_SEL:.*]] = phi i32 [ %[[NORMAL_OR_SUBNORMAL]], %[[BB_NOT_INF]] ], [ 516, %[[BB_INF]] ]
-// LLVM-NEXT: br label %[[BB_CONT1:.*]]
-// LLVM: [[BB_CONT1]]:
-// LLVM-NEXT: br label %[[BB_MERGE1]]
-// LLVM: [[BB_MERGE1]]:
-// LLVM-NEXT: %[[PHI_NAN_SEL:.*]] = phi i32 [ %[[PHI_INF_SEL]], %[[BB_CONT1]] ], [ 3, %[[BB_NAN]] ]
-// LLVM-NEXT: br label %[[BB_CONT2:.*]]
-// LLVM: [[BB_CONT2]]:
-// LLVM-NEXT: br label %[[BB_RET]]
-// LLVM: [[BB_RET]]:
-// LLVM-NEXT: %[[PHI_FINAL:.*]] = phi i32 [ %[[PHI_NAN_SEL]], %[[BB_CONT2]] ], [ 96, %[[BB_ZERO]] ]
-// LLVM-NEXT: br label %[[BB_EXIT:.*]]
-// LLVM: [[BB_EXIT]]:
-
-// OGCG: %[[CMP_ZERO:.+]] = fcmp oeq float %[[VAL:.+]],
-// OGCG-NEXT: br i1 %[[CMP_ZERO]], label %[[BB_RET:.+]], label %[[BB_NOT_ZERO:.+]]
-// OGCG: [[BB_RET]]:
-// OGCG-NEXT: %[[PHI:.+]] = phi i32 [ 96, %[[BB_ENTRY:.+]] ], [ 3, %[[BB_NOT_ZERO]] ], [ 516, %[[BB_NOT_NAN:.+]] ], [ %[[SEL:.+]], %[[BB_NOT_INF:.+]] ]
-// OGCG: [[BB_NOT_ZERO]]:
-// OGCG-NEXT: %[[CMP_NAN:.+]] = fcmp uno float %[[VAL]], %[[VAL]]
-// OGCG-NEXT: br i1 %[[CMP_NAN]], label %[[BB_RET]], label %[[BB_NOT_NAN]]
-// OGCG: [[BB_NOT_NAN]]:
-// OGCG-NEXT: %[[FABS:.+]] = call float @llvm.fabs.f32(float %[[VAL]])
-// OGCG-NEXT: %[[CMP_INF:.+]] = fcmp oeq float %[[FABS]],
-// OGCG-NEXT: br i1 %[[CMP_INF]], label %[[BB_RET]], label %[[BB_NOT_INF]]
-// OGCG: [[BB_NOT_INF]]:
-// OGCG-NEXT: %[[CMP_NORMAL:.+]] = fcmp uge float %[[FABS]],
-// OGCG-NEXT: %[[SEL]] = select i1 %[[CMP_NORMAL]], i32 264, i32 144
-// OGCG-NEXT: br label %[[BB_RET]]
+// LLVM: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS1]]
+// LLVM: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS2]]
+// LLVM: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS3]]
+// LLVM: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: phi i32
+
+// OGCG: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS1]]
+// OGCG: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS2]]
+// OGCG: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS3]]
+// OGCG: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: phi i32
}
void test_fpclassify_subnormal(){
@@ -235,55 +140,23 @@ void test_fpclassify_subnormal(){
// CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
// CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else %[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
-// LLVM: %[[VAL:.*]] = load float, ptr
-// LLVM-NEXT: %[[IS_ZERO:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 96)
-// LLVM-NEXT: br i1 %[[IS_ZERO]], label %[[BB_ZERO:.*]], label %[[BB_NOT_ZERO:.*]]
-// LLVM: [[BB_ZERO]]:
-// LLVM-NEXT: br label %[[BB_RET:.*]]
-// LLVM: [[BB_NOT_ZERO]]:
-// LLVM-NEXT: %[[IS_NAN:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 3)
-// LLVM-NEXT: br i1 %[[IS_NAN]], label %[[BB_NAN:.*]], label %[[BB_NOT_NAN:.*]]
-// LLVM: [[BB_NAN]]:
-// LLVM-NEXT: br label %[[BB_MERGE1:.*]]
-// LLVM: [[BB_NOT_NAN]]:
-// LLVM-NEXT: %[[IS_INF:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 516)
-// LLVM-NEXT: br i1 %[[IS_INF]], label %[[BB_INF:.*]], label %[[BB_NOT_INF:.*]]
-// LLVM: [[BB_INF]]:
-// LLVM-NEXT: br label %[[BB_MERGE2:.*]]
-// LLVM: [[BB_NOT_INF]]:
-// LLVM-NEXT: %[[IS_NORMAL:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 264)
-// LLVM-NEXT: %[[NORMAL_OR_SUBNORMAL:.*]] = select i1 %[[IS_NORMAL]], i32 264, i32 144
-// LLVM-NEXT: br label %[[BB_MERGE2]]
-// LLVM: [[BB_MERGE2]]:
-// LLVM-NEXT: %[[PHI_INF_SEL:.*]] = phi i32 [ %[[NORMAL_OR_SUBNORMAL]], %[[BB_NOT_INF]] ], [ 516, %[[BB_INF]] ]
-// LLVM-NEXT: br label %[[BB_CONT1:.*]]
-// LLVM: [[BB_CONT1]]:
-// LLVM-NEXT: br label %[[BB_MERGE1]]
-// LLVM: [[BB_MERGE1]]:
-// LLVM-NEXT: %[[PHI_NAN_SEL:.*]] = phi i32 [ %[[PHI_INF_SEL]], %[[BB_CONT1]] ], [ 3, %[[BB_NAN]] ]
-// LLVM-NEXT: br label %[[BB_CONT2:.*]]
-// LLVM: [[BB_CONT2]]:
-// LLVM-NEXT: br label %[[BB_RET]]
-// LLVM: [[BB_RET]]:
-// LLVM-NEXT: %[[PHI_FINAL:.*]] = phi i32 [ %[[PHI_NAN_SEL]], %[[BB_CONT2]] ], [ 96, %[[BB_ZERO]] ]
-// LLVM-NEXT: br label %[[BB_EXIT:.*]]
-// LLVM: [[BB_EXIT]]:
-
-// OGCG: %[[CMP_ZERO:.+]] = fcmp oeq float %[[VAL:.+]],
-// OGCG-NEXT: br i1 %[[CMP_ZERO]], label %[[BB_RET:.+]], label %[[BB_NOT_ZERO:.+]]
-// OGCG: [[BB_RET]]:
-// OGCG-NEXT: %[[PHI:.+]] = phi i32 [ 96, %[[BB_ENTRY:.+]] ], [ 3, %[[BB_NOT_ZERO]] ], [ 516, %[[BB_NOT_NAN:.+]] ], [ %[[SEL:.+]], %[[BB_NOT_INF:.+]] ]
-// OGCG: [[BB_NOT_ZERO]]:
-// OGCG-NEXT: %[[CMP_NAN:.+]] = fcmp uno float %[[VAL]], %[[VAL]]
-// OGCG-NEXT: br i1 %[[CMP_NAN]], label %[[BB_RET]], label %[[BB_NOT_NAN]]
-// OGCG: [[BB_NOT_NAN]]:
-// OGCG-NEXT: %[[FABS:.+]] = call float @llvm.fabs.f32(float %[[VAL]])
-// OGCG-NEXT: %[[CMP_INF:.+]] = fcmp oeq float %[[FABS]],
-// OGCG-NEXT: br i1 %[[CMP_INF]], label %[[BB_RET]], label %[[BB_NOT_INF]]
-// OGCG: [[BB_NOT_INF]]:
-// OGCG-NEXT: %[[CMP_NORMAL:.+]] = fcmp uge float %[[FABS]],
-// OGCG-NEXT: %[[SEL]] = select i1 %[[CMP_NORMAL]], i32 264, i32 144
-// OGCG-NEXT: br label %[[BB_RET]]
+// LLVM: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS1]]
+// LLVM: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS2]]
+// LLVM: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS3]]
+// LLVM: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: phi i32
+
+// OGCG: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS1]]
+// OGCG: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS2]]
+// OGCG: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS3]]
+// OGCG: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: phi i32
}
void test_fpclassify_zero(){
@@ -304,53 +177,21 @@ void test_fpclassify_zero(){
// CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
// CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else %[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
-// LLVM: %[[VAL:.*]] = load float, ptr
-// LLVM-NEXT: %[[IS_ZERO:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 96)
-// LLVM-NEXT: br i1 %[[IS_ZERO]], label %[[BB_ZERO:.*]], label %[[BB_NOT_ZERO:.*]]
-// LLVM: [[BB_ZERO]]:
-// LLVM-NEXT: br label %[[BB_RET:.*]]
-// LLVM: [[BB_NOT_ZERO]]:
-// LLVM-NEXT: %[[IS_NAN:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 3)
-// LLVM-NEXT: br i1 %[[IS_NAN]], label %[[BB_NAN:.*]], label %[[BB_NOT_NAN:.*]]
-// LLVM: [[BB_NAN]]:
-// LLVM-NEXT: br label %[[BB_MERGE1:.*]]
-// LLVM: [[BB_NOT_NAN]]:
-// LLVM-NEXT: %[[IS_INF:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 516)
-// LLVM-NEXT: br i1 %[[IS_INF]], label %[[BB_INF:.*]], label %[[BB_NOT_INF:.*]]
-// LLVM: [[BB_INF]]:
-// LLVM-NEXT: br label %[[BB_MERGE2:.*]]
-// LLVM: [[BB_NOT_INF]]:
-// LLVM-NEXT: %[[IS_NORMAL:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 264)
-// LLVM-NEXT: %[[NORMAL_OR_SUBNORMAL:.*]] = select i1 %[[IS_NORMAL]], i32 264, i32 144
-// LLVM-NEXT: br label %[[BB_MERGE2]]
-// LLVM: [[BB_MERGE2]]:
-// LLVM-NEXT: %[[PHI_INF_SEL:.*]] = phi i32 [ %[[NORMAL_OR_SUBNORMAL]], %[[BB_NOT_INF]] ], [ 516, %[[BB_INF]] ]
-// LLVM-NEXT: br label %[[BB_CONT1:.*]]
-// LLVM: [[BB_CONT1]]:
-// LLVM-NEXT: br label %[[BB_MERGE1]]
-// LLVM: [[BB_MERGE1]]:
-// LLVM-NEXT: %[[PHI_NAN_SEL:.*]] = phi i32 [ %[[PHI_INF_SEL]], %[[BB_CONT1]] ], [ 3, %[[BB_NAN]] ]
-// LLVM-NEXT: br label %[[BB_CONT2:.*]]
-// LLVM: [[BB_CONT2]]:
-// LLVM-NEXT: br label %[[BB_RET]]
-// LLVM: [[BB_RET]]:
-// LLVM-NEXT: %[[PHI_FINAL:.*]] = phi i32 [ %[[PHI_NAN_SEL]], %[[BB_CONT2]] ], [ 96, %[[BB_ZERO]] ]
-// LLVM-NEXT: br label %[[BB_EXIT:.*]]
-// LLVM: [[BB_EXIT]]:
-
-// OGCG: %[[CMP_ZERO:.+]] = fcmp oeq float %[[VAL:.+]],
-// OGCG-NEXT: br i1 %[[CMP_ZERO]], label %[[BB_RET:.+]], label %[[BB_NOT_ZERO:.+]]
-// OGCG: [[BB_RET]]:
-// OGCG-NEXT: %[[PHI:.+]] = phi i32 [ 96, %[[BB_ENTRY:.+]] ], [ 3, %[[BB_NOT_ZERO]] ], [ 516, %[[BB_NOT_NAN:.+]] ], [ %[[SEL:.+]], %[[BB_NOT_INF:.+]] ]
-// OGCG: [[BB_NOT_ZERO]]:
-// OGCG-NEXT: %[[CMP_NAN:.+]] = fcmp uno float %[[VAL]], %[[VAL]]
-// OGCG-NEXT: br i1 %[[CMP_NAN]], label %[[BB_RET]], label %[[BB_NOT_NAN]]
-// OGCG: [[BB_NOT_NAN]]:
-// OGCG-NEXT: %[[FABS:.+]] = call float @llvm.fabs.f32(float %[[VAL]])
-// OGCG-NEXT: %[[CMP_INF:.+]] = fcmp oeq float %[[FABS]],
-// OGCG-NEXT: br i1 %[[CMP_INF]], label %[[BB_RET]], label %[[BB_NOT_INF]]
-// OGCG: [[BB_NOT_INF]]:
-// OGCG-NEXT: %[[CMP_NORMAL:.+]] = fcmp uge float %[[FABS]],
-// OGCG-NEXT: %[[SEL]] = select i1 %[[CMP_NORMAL]], i32 264, i32 144
-// OGCG-NEXT: br label %[[BB_RET]]
+// LLVM: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS1]]
+// LLVM: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS2]]
+// LLVM: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: br i1 %[[FPCLASS3]]
+// LLVM: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// LLVM: phi i32
+
+// OGCG: %[[FPCLASS1:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL:.*]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS1]]
+// OGCG: %[[FPCLASS2:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS2]]
+// OGCG: %[[FPCLASS3:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: br i1 %[[FPCLASS3]]
+// OGCG: %[[FPCLASS4:.*]] = call i1 @llvm.is.fpclass.f32(float %[[VAL]], i32 {{.*}})
+// OGCG: phi i32
}
diff --git a/clang/test/CodeGen/builtin-fpclassify.c b/clang/test/CodeGen/builtin-fpclassify.c
new file mode 100644
index 0000000000000..d9ae3d1a5218a
--- /dev/null
+++ b/clang/test/CodeGen/builtin-fpclassify.c
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+#define FP_NAN 3
+#define FP_INFINITE 516
+#define FP_ZERO 96
+#define FP_SUBNORMAL 144
+#define FP_NORMAL 264
+
+void test_fpclassify_nan() {
+ float nanValue = 0.0f / 0.0f;
+ __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,
+ nanValue);
+// CHECK-LABEL: entry:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 3)
+// CHECK: br i1 %{{.*}}, label %fpclassify_end, label %fpclassify_not_nan
+// CHECK-LABEL: fpclassify_not_nan:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 516)
+// CHECK-LABEL: fpclassify_not_infinite:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 264)
+// CHECK-LABEL: fpclassify_not_normal:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 144)
+// CHECK-LABEL: fpclassify_end:
+// CHECK: %fpclassify_result = phi i32 [ 3, %entry ], [ 516, %fpclassify_not_nan ], [ 264, %fpclassify_not_infinite ], [ 144, %fpclassify_not_normal ], [ 96, %fpclassify_not_subnormal ]
+}
+
+void test_fpclassify_inf() {
+ float infValue = 1.0f / 0.0f;
+ __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,
+ infValue);
+// CHECK-LABEL: entry:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 3)
+// CHECK: br i1 %{{.*}}, label %fpclassify_end, label %fpclassify_not_nan
+// CHECK-LABEL: fpclassify_not_nan:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 516)
+// CHECK-LABEL: fpclassify_not_infinite:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 264)
+// CHECK-LABEL: fpclassify_not_normal:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 144)
+// CHECK-LABEL: fpclassify_end:
+// CHECK: %fpclassify_result = phi i32 [ 3, %entry ], [ 516, %fpclassify_not_nan ], [ 264, %fpclassify_not_infinite ], [ 144, %fpclassify_not_normal ], [ 96, %fpclassify_not_subnormal ]
+}
+
+void test_fpclassify_normal() {
+ float normalValue = 1.0f;
+ __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,
+ normalValue);
+// CHECK-LABEL: entry:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 3)
+// CHECK: br i1 %{{.*}}, label %fpclassify_end, label %fpclassify_not_nan
+// CHECK-LABEL: fpclassify_not_nan:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 516)
+// CHECK-LABEL: fpclassify_not_infinite:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 264)
+// CHECK-LABEL: fpclassify_not_normal:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 144)
+// CHECK-LABEL: fpclassify_end:
+// CHECK: %fpclassify_result = phi i32 [ 3, %entry ], [ 516, %fpclassify_not_nan ], [ 264, %fpclassify_not_infinite ], [ 144, %fpclassify_not_normal ], [ 96, %fpclassify_not_subnormal ]
+}
+
+void test_fpclassify_subnormal() {
+ float subnormalValue = 1.0e-40f;
+ __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,
+ subnormalValue);
+// CHECK-LABEL: entry:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 3)
+// CHECK: br i1 %{{.*}}, label %fpclassify_end, label %fpclassify_not_nan
+// CHECK-LABEL: fpclassify_not_nan:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 516)
+// CHECK-LABEL: fpclassify_not_infinite:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 264)
+// CHECK-LABEL: fpclassify_not_normal:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 144)
+// CHECK-LABEL: fpclassify_end:
+// CHECK: %fpclassify_result = phi i32 [ 3, %entry ], [ 516, %fpclassify_not_nan ], [ 264, %fpclassify_not_infinite ], [ 144, %fpclassify_not_normal ], [ 96, %fpclassify_not_subnormal ]
+}
+
+void test_fpclassify_zero() {
+ float zeroValue = 0.0f;
+ __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,
+ zeroValue);
+// CHECK-LABEL: entry:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 3)
+// CHECK: br i1 %{{.*}}, label %fpclassify_end, label %fpclassify_not_nan
+// CHECK-LABEL: fpclassify_not_nan:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 516)
+// CHECK-LABEL: fpclassify_not_infinite:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 264)
+// CHECK-LABEL: fpclassify_not_normal:
+// CHECK: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 144)
+// CHECK-LABEL: fpclassify_end:
+// CHECK: %fpclassify_result = phi i32 [ 3, %entry ], [ 516, %fpclassify_not_nan ], [ 264, %fpclassify_not_infinite ], [ 144, %fpclassify_not_normal ], [ 96, %fpclassify_not_subnormal ]
+}
diff --git a/clang/test/Headers/nvptx_device_math_macro.cpp b/clang/test/Headers/nvptx_device_math_macro.cpp
index 3faf527daf113..e360401e0e2d3 100644
--- a/clang/test/Headers/nvptx_device_math_macro.cpp
+++ b/clang/test/Headers/nvptx_device_math_macro.cpp
@@ -8,10 +8,10 @@
#pragma omp declare target
int use_macro() {
double a(0);
-// CHECK-NOT: call {{.*}}
-// CHECK: call double @llvm.fabs.f64(double
-// CHECK-NOT: call {{.*}}
-// CHECK: ret i32 %conv
return (std::fpclassify(a) != FP_ZERO);
+// CHECK: call i1 @llvm.is.fpclass.f64(double {{.*}}, i32 {{.*}})
+// CHECK: call i1 @llvm.is.fpclass.f64(double {{.*}}, i32 {{.*}})
+// CHECK: call i1 @llvm.is.fpclass.f64(double {{.*}}, i32 {{.*}})
+// CHECK: call i1 @llvm.is.fpclass.f64(double {{.*}}, i32 {{.*}})
}
#pragma omp end declare target
More information about the cfe-commits
mailing list