[clang] [llvm] [AsmWriter] Print `nan`, `pinf`, and `ninf` when applicable (PR #105618)

via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 21 22:38:50 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-llvm-globalisel

Author: Min-Yih Hsu (mshockwave)

<details>
<summary>Changes</summary>

Instead of hexidecimal values, print `nan`, `pinf`, and `ninf` when the floating point constant is equal to positive quiet NaN with zero payload, positive infinity, and negative infinity, respectively.

This patch also introduce `-force-print-hex-special-fp` to revert back to the old behavior.

-----

This PR stacks on top of #<!-- -->102790 

---

Patch is 455.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/105618.diff


111 Files Affected:

- (modified) clang/test/CodeGen/builtin-nan-exception.c (+3-3) 
- (modified) clang/test/CodeGen/builtin-nan-legacy.c (+2-2) 
- (modified) clang/test/CodeGen/builtin-nanf.c (+1-1) 
- (modified) clang/test/CodeGen/builtin_Float16.c (+3-3) 
- (modified) clang/test/CodeGen/builtins.c (+10-10) 
- (modified) clang/test/CodeGen/complex-init-list.c (+1-1) 
- (modified) clang/test/CodeGen/ext-vector.c (+1-1) 
- (modified) clang/test/CodeGen/isfpclass.c (+1-1) 
- (modified) clang/test/CodeGen/math-builtins-long.c (+8-8) 
- (modified) clang/test/CodeGen/mips-unsupported-nan.c (+2-2) 
- (modified) clang/test/CodeGen/strictfp_builtins.c (+2-2) 
- (modified) clang/test/Headers/cuda_wrapper_algorithm.cu (+4-4) 
- (modified) clang/test/Lexer/11-27-2007-FloatLiterals.c (+1-1) 
- (modified) llvm/docs/LangRef.rst (+36-11) 
- (modified) llvm/lib/AsmParser/LLParser.cpp (+34) 
- (modified) llvm/lib/IR/AsmWriter.cpp (+29-8) 
- (modified) llvm/test/Assembler/2002-04-07-InfConstant.ll (+1-1) 
- (modified) llvm/test/Assembler/bfloat.ll (+3-3) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-fminimum-fmaximum.mir (+8-8) 
- (added) llvm/test/Feature/float-special.ll (+27) 
- (modified) llvm/test/Feature/float.ll (+4) 
- (modified) llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll (+12-12) 
- (modified) llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll (+6-6) 
- (modified) llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll (+1-1) 
- (modified) llvm/test/Transforms/Attributor/nofpclass-select.ll (+14-14) 
- (modified) llvm/test/Transforms/Attributor/nofpclass.ll (+23-9) 
- (modified) llvm/test/Transforms/DCE/calls-errno.ll (+4-4) 
- (modified) llvm/test/Transforms/EarlyCSE/atan.ll (+7-7) 
- (modified) llvm/test/Transforms/GVNHoist/hoist-call.ll (+7-7) 
- (modified) llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/2007-03-25-BadShiftMask.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/2009-01-19-fmod-constant-float-specials.ll (+17-17) 
- (modified) llvm/test/Transforms/InstCombine/and-fcmp.ll (+24-24) 
- (modified) llvm/test/Transforms/InstCombine/atomicrmw.ll (+4-4) 
- (modified) llvm/test/Transforms/InstCombine/binop-select.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/canonicalize-fcmp-inf.ll (+11-11) 
- (modified) llvm/test/Transforms/InstCombine/cast-int-fcmp-eq-0.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll (+6-6) 
- (modified) llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll (+60-60) 
- (modified) llvm/test/Transforms/InstCombine/fcmp-range-check-idiom.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/fdiv.ll (+10-10) 
- (modified) llvm/test/Transforms/InstCombine/fma.ll (+17-17) 
- (modified) llvm/test/Transforms/InstCombine/fneg.ll (+6-6) 
- (modified) llvm/test/Transforms/InstCombine/fold-calls.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll (+5-5) 
- (modified) llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll (+10-10) 
- (modified) llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll (+4-4) 
- (modified) llvm/test/Transforms/InstCombine/intrinsic-select.ll (+8-8) 
- (modified) llvm/test/Transforms/InstCombine/is_fpclass.ll (+32-32) 
- (modified) llvm/test/Transforms/InstCombine/known-bits.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/maximum.ll (+8-8) 
- (modified) llvm/test/Transforms/InstCombine/maxnum.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/minimum.ll (+8-8) 
- (modified) llvm/test/Transforms/InstCombine/minnum.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/nan.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/nanl-fp128.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/nanl-fp80.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/nanl-ppc-fp128.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/pow-1.ll (+12-12) 
- (modified) llvm/test/Transforms/InstCombine/pow-3.ll (+2-2) 
- (modified) llvm/test/Transforms/InstCombine/pow-exp.ll (+8-8) 
- (modified) llvm/test/Transforms/InstCombine/pow-sqrt.ll (+9-9) 
- (modified) llvm/test/Transforms/InstCombine/remquo.ll (+3-3) 
- (modified) llvm/test/Transforms/InstCombine/shufflevec-constant-inseltpoison.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/shufflevec-constant.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll (+29-29) 
- (modified) llvm/test/Transforms/InstCombine/sqrt.ll (+1-1) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/WebAssembly/trunc.ll (+24-24) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/calls.ll (+1-1) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/cast.ll (+5-5) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/fma.ll (+21-21) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll (+64-64) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll (+12-12) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/vector-undef-elts-inseltpoison.ll (+2-2) 
- (modified) llvm/test/Transforms/InstSimplify/ConstProp/vector-undef-elts.ll (+2-2) 
- (modified) llvm/test/Transforms/InstSimplify/X86/fp-nan-strictfp.ll (+52-52) 
- (modified) llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll (+15-15) 
- (modified) llvm/test/Transforms/InstSimplify/call.ll (+15-15) 
- (modified) llvm/test/Transforms/InstSimplify/canonicalize.ll (+17-17) 
- (modified) llvm/test/Transforms/InstSimplify/constfold-constrained.ll (+8-8) 
- (modified) llvm/test/Transforms/InstSimplify/exp10.ll (+16-16) 
- (modified) llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll (+16-16) 
- (modified) llvm/test/Transforms/InstSimplify/floating-point-compare.ll (+6-6) 
- (modified) llvm/test/Transforms/InstSimplify/fminmax-folds.ll (+27-27) 
- (modified) llvm/test/Transforms/InstSimplify/fp-nan.ll (+4-4) 
- (modified) llvm/test/Transforms/InstSimplify/fp-undef-poison-strictfp.ll (+14-14) 
- (modified) llvm/test/Transforms/InstSimplify/fp-undef-poison.ll (+13-13) 
- (modified) llvm/test/Transforms/InstSimplify/frexp.ll (+15-15) 
- (modified) llvm/test/Transforms/InstSimplify/known-never-infinity.ll (+55-55) 
- (modified) llvm/test/Transforms/InstSimplify/known-never-nan.ll (+4-4) 
- (modified) llvm/test/Transforms/InstSimplify/ldexp.ll (+13-13) 
- (modified) llvm/test/Transforms/InstSimplify/strictfp-fadd.ll (+4-4) 
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/scalable-reduction-inloop-cond.ll (+1-1) 
- (modified) llvm/test/Transforms/LoopVectorize/RISCV/vectorize-force-tail-with-evl-inloop-reduction.ll (+2-2) 
- (modified) llvm/test/Transforms/LoopVectorize/reduction-inloop-cond.ll (+1-1) 
- (modified) llvm/test/Transforms/LoopVectorize/select-cmp-multiuse.ll (+3-3) 
- (modified) llvm/test/Transforms/PreISelIntrinsicLowering/expand-vp.ll (+7-7) 
- (modified) llvm/test/Transforms/Reassociate/pr42349.ll (+1-1) 
- (modified) llvm/test/Transforms/SCCP/float-nan-simplification.ll (+2-2) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/buildvector-shuffle.ll (+5-5) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/catchswitch.ll (+8-8) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/fabs-cost-softfp.ll (+1-1) 
- (modified) llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll (+1-1) 
- (modified) llvm/test/Transforms/SimplifyCFG/speculate-math.ll (+8-8) 
- (modified) llvm/test/Transforms/Util/libcalls-shrinkwrap-double.ll (+8-8) 
- (modified) llvm/test/Transforms/Util/libcalls-shrinkwrap-float.ll (+8-8) 
- (modified) llvm/test/Transforms/Util/libcalls-shrinkwrap-long-double.ll (+8-8) 
- (modified) llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll (+16-16) 
- (modified) llvm/test/tools/llvm-reduce/reduce-operands-fp.ll (+16-16) 
- (modified) llvm/unittests/AsmParser/AsmParserTest.cpp (+34) 


``````````diff
diff --git a/clang/test/CodeGen/builtin-nan-exception.c b/clang/test/CodeGen/builtin-nan-exception.c
index 7445411ddf89ea..ba8bbf9c3b1d7d 100644
--- a/clang/test/CodeGen/builtin-nan-exception.c
+++ b/clang/test/CodeGen/builtin-nan-exception.c
@@ -8,7 +8,7 @@
 // An SNaN with no payload is formed by setting the bit after the
 // the quiet bit (MSB of the significand).
 
-// CHECK: float 0x7FF8000000000000, float 0x7FF4000000000000
+// CHECK: float nan, float 0x7FF4000000000000
 
 float f[] = {
   __builtin_nanf(""),
@@ -22,14 +22,14 @@ float f[] = {
 // but that should not cause a compilation error in the default
 // (ignore FP exceptions) mode.
 
-// CHECK: float 0x7FF8000000000000, float 0x7FFC000000000000
+// CHECK: float nan, float 0x7FFC000000000000
 
 float converted_to_float[] = {
   __builtin_nan(""),
   __builtin_nans(""),
 };
 
-// CHECK: double 0x7FF8000000000000, double 0x7FF4000000000000
+// CHECK: double nan, double 0x7FF4000000000000
 
 double d[] = {
   __builtin_nan(""),
diff --git a/clang/test/CodeGen/builtin-nan-legacy.c b/clang/test/CodeGen/builtin-nan-legacy.c
index de6c15379a4ddd..989c6976fb9500 100644
--- a/clang/test/CodeGen/builtin-nan-legacy.c
+++ b/clang/test/CodeGen/builtin-nan-legacy.c
@@ -1,6 +1,6 @@
 // RUN: %clang -target mipsel-unknown-linux -mnan=legacy -emit-llvm -S %s -o - | FileCheck %s
-// CHECK: float 0x7FFC000000000000, float 0x7FF8000000000000
-// CHECK: double 0x7FF4000000000000, double 0x7FF8000000000000
+// CHECK: float 0x7FFC000000000000, float nan
+// CHECK: double 0x7FF4000000000000, double nan
 
 // The first line shows an unintended consequence.
 // __builtin_nan() creates a legacy QNAN double with an empty payload
diff --git a/clang/test/CodeGen/builtin-nanf.c b/clang/test/CodeGen/builtin-nanf.c
index ae37c9dc807793..a6ef126da33f92 100644
--- a/clang/test/CodeGen/builtin-nanf.c
+++ b/clang/test/CodeGen/builtin-nanf.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o %t %s
-// RUN: grep 'float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000020000000, float 0x7FF8000000000000, float 0x7FF80001E0000000, float 0x7FF8001E00000000, float 0x7FF801E000000000, float 0x7FF81E0000000000, float 0x7FF9E00000000000, float 0x7FFFFFFFE0000000' %t
+// RUN: grep 'float nan, float nan, float 0x7FF8000020000000, float nan, float 0x7FF80001E0000000, float 0x7FF8001E00000000, float 0x7FF801E000000000, float 0x7FF81E0000000000, float 0x7FF9E00000000000, float 0x7FFFFFFFE0000000' %t
 
 float n[] = {
   __builtin_nanf("0"),
diff --git a/clang/test/CodeGen/builtin_Float16.c b/clang/test/CodeGen/builtin_Float16.c
index 099d2ad5697e34..9d3c481fa43c08 100644
--- a/clang/test/CodeGen/builtin_Float16.c
+++ b/clang/test/CodeGen/builtin_Float16.c
@@ -6,11 +6,11 @@
 void test_float16_builtins(void) {
   volatile _Float16 res;
 
-  // CHECK: store volatile half 0xH7C00, ptr %res, align 2
+  // CHECK: store volatile half pinf, ptr %res, align 2
   res = __builtin_huge_valf16();
-  // CHECK: store volatile half 0xH7C00, ptr %res, align 2
+  // CHECK: store volatile half pinf, ptr %res, align 2
   res = __builtin_inff16();
-  // CHECK: store volatile half 0xH7E00, ptr %res, align 2
+  // CHECK: store volatile half nan, ptr %res, align 2
   res = __builtin_nanf16("");
   // CHECK: store volatile half 0xH7D00, ptr %res, align 2
   res = __builtin_nansf16("");
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 6383a3c65e3750..28ac628952655f 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -169,12 +169,12 @@ void bar(void) {
   // 0xAE98 == 1010111010011000
   // 0x15D3 == 1010111010011
 
-  f = __builtin_huge_valf();     // CHECK: float    0x7FF0000000000000
-  d = __builtin_huge_val();      // CHECK: double   0x7FF0000000000000
-  ld = __builtin_huge_vall();    // CHECK: x86_fp80 0xK7FFF8000000000000000
-  f = __builtin_nanf("");        // CHECK: float    0x7FF8000000000000
-  d = __builtin_nan("");         // CHECK: double   0x7FF8000000000000
-  ld = __builtin_nanl("");       // CHECK: x86_fp80 0xK7FFFC000000000000000
+  f = __builtin_huge_valf();     // CHECK: float    pinf
+  d = __builtin_huge_val();      // CHECK: double   pinf
+  ld = __builtin_huge_vall();    // CHECK: x86_fp80 pinf
+  f = __builtin_nanf("");        // CHECK: float    nan
+  d = __builtin_nan("");         // CHECK: double   nan
+  ld = __builtin_nanl("");       // CHECK: x86_fp80 nan
   f = __builtin_nanf("0xAE98");  // CHECK: float    0x7FF815D300000000
   d = __builtin_nan("0xAE98");   // CHECK: double   0x7FF800000000AE98
   ld = __builtin_nanl("0xAE98"); // CHECK: x86_fp80 0xK7FFFC00000000000AE98
@@ -238,7 +238,7 @@ void test_float_builtins(__fp16 *H, float F, double D, long double LD) {
 
   res = __builtin_isinf_sign(*H);
   // CHECK:  %[[ABS:.*]] = call half @llvm.fabs.f16(half %[[ARG:.*]])
-  // CHECK:  %[[ISINF:.*]] = fcmp oeq half %[[ABS]], 0xH7C00
+  // CHECK:  %[[ISINF:.*]] = fcmp oeq half %[[ABS]], pinf
   // CHECK:  %[[BITCAST:.*]] = bitcast half %[[ARG]] to i16
   // CHECK:  %[[ISNEG:.*]] = icmp slt i16 %[[BITCAST]], 0
   // CHECK:  %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
@@ -246,7 +246,7 @@ void test_float_builtins(__fp16 *H, float F, double D, long double LD) {
 
   res = __builtin_isinf_sign(F);
   // CHECK:  %[[ABS:.*]] = call float @llvm.fabs.f32(float %[[ARG:.*]])
-  // CHECK:  %[[ISINF:.*]] = fcmp oeq float %[[ABS]], 0x7FF0000000000000
+  // CHECK:  %[[ISINF:.*]] = fcmp oeq float %[[ABS]], pinf
   // CHECK:  %[[BITCAST:.*]] = bitcast float %[[ARG]] to i32
   // CHECK:  %[[ISNEG:.*]] = icmp slt i32 %[[BITCAST]], 0
   // CHECK:  %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
@@ -254,7 +254,7 @@ void test_float_builtins(__fp16 *H, float F, double D, long double LD) {
 
   res = __builtin_isinf_sign(D);
   // CHECK:  %[[ABS:.*]] = call double @llvm.fabs.f64(double %[[ARG:.*]])
-  // CHECK:  %[[ISINF:.*]] = fcmp oeq double %[[ABS]], 0x7FF0000000000000
+  // CHECK:  %[[ISINF:.*]] = fcmp oeq double %[[ABS]], pinf
   // CHECK:  %[[BITCAST:.*]] = bitcast double %[[ARG]] to i64
   // CHECK:  %[[ISNEG:.*]] = icmp slt i64 %[[BITCAST]], 0
   // CHECK:  %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
@@ -262,7 +262,7 @@ void test_float_builtins(__fp16 *H, float F, double D, long double LD) {
 
   res = __builtin_isinf_sign(LD);
   // CHECK:  %[[ABS:.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 %[[ARG:.*]])
-  // CHECK:  %[[ISINF:.*]] = fcmp oeq x86_fp80 %[[ABS]], 0xK7FFF8000000000000000
+  // CHECK:  %[[ISINF:.*]] = fcmp oeq x86_fp80 %[[ABS]], pinf
   // CHECK:  %[[BITCAST:.*]] = bitcast x86_fp80 %[[ARG]] to i80
   // CHECK:  %[[ISNEG:.*]] = icmp slt i80 %[[BITCAST]], 0
   // CHECK:  %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
diff --git a/clang/test/CodeGen/complex-init-list.c b/clang/test/CodeGen/complex-init-list.c
index 262b44d213b3f1..90a08669065002 100644
--- a/clang/test/CodeGen/complex-init-list.c
+++ b/clang/test/CodeGen/complex-init-list.c
@@ -5,7 +5,7 @@
 // extensive description and test in test/Sema/complex-init-list.c.)
 
 _Complex float x = { 1.0f, 1.0f/0.0f };
-// CHECK: @x ={{.*}} global { float, float } { float 1.000000e+00, float 0x7FF0000000000000 }, align 4
+// CHECK: @x ={{.*}} global { float, float } { float 1.000000e+00, float pinf }, align 4
 
 _Complex float f(float x, float y) { _Complex float z = { x, y }; return z; }
 // CHECK-LABEL: define{{.*}} <2 x float> @f
diff --git a/clang/test/CodeGen/ext-vector.c b/clang/test/CodeGen/ext-vector.c
index db8baf054ac7b8..bd2600a3061b5f 100644
--- a/clang/test/CodeGen/ext-vector.c
+++ b/clang/test/CodeGen/ext-vector.c
@@ -8,7 +8,7 @@ typedef __attribute__(( ext_vector_type(4) )) unsigned int uint4;
 // CHECK: @foo = {{(dso_local )?}}global <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>
 float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
 
-// CHECK: @bar = {{(dso_local )?}}constant <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 0x7FF0000000000000>
+// CHECK: @bar = {{(dso_local )?}}constant <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float pinf>
 const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() };
 
 // CHECK: @test1
diff --git a/clang/test/CodeGen/isfpclass.c b/clang/test/CodeGen/isfpclass.c
index a0e04eaad5929d..3cd3a475e49c1d 100644
--- a/clang/test/CodeGen/isfpclass.c
+++ b/clang/test/CodeGen/isfpclass.c
@@ -5,7 +5,7 @@
 // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[TMP0:%.*]] = tail call float @llvm.fabs.f32(float [[X]])
-// CHECK-NEXT:    [[TMP1:%.*]] = fcmp one float [[TMP0]], 0x7FF0000000000000
+// CHECK-NEXT:    [[TMP1:%.*]] = fcmp one float [[TMP0]], pinf
 // CHECK-NEXT:    ret i1 [[TMP1]]
 //
 _Bool check_isfpclass_finite(float x) {
diff --git a/clang/test/CodeGen/math-builtins-long.c b/clang/test/CodeGen/math-builtins-long.c
index 183349e0f01734..f63099db04c07a 100644
--- a/clang/test/CodeGen/math-builtins-long.c
+++ b/clang/test/CodeGen/math-builtins-long.c
@@ -40,16 +40,16 @@ void foo(long double f, long double *l, int *i, const char *c) {
   // PPCF128: call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %{{.+}})
   __builtin_frexpl(f,i);
 
-  // F80: store x86_fp80 0xK7FFF8000000000000000, ptr
-  // PPC: store ppc_fp128 0xM7FF00000000000000000000000000000, ptr
-  // X86F128: store fp128 0xL00000000000000007FFF000000000000, ptr
-  // PPCF128: store fp128 0xL00000000000000007FFF000000000000, ptr
+  // F80: store x86_fp80 pinf, ptr
+  // PPC: store ppc_fp128 pinf, ptr
+  // X86F128: store fp128 pinf, ptr
+  // PPCF128: store fp128 pinf, ptr
   *l = __builtin_huge_vall();
 
-  // F80: store x86_fp80 0xK7FFF8000000000000000, ptr
-  // PPC: store ppc_fp128 0xM7FF00000000000000000000000000000, ptr
-  // X86F128: store fp128 0xL00000000000000007FFF000000000000, ptr
-  // PPCF128: store fp128 0xL00000000000000007FFF000000000000, ptr
+  // F80: store x86_fp80 pinf, ptr
+  // PPC: store ppc_fp128 pinf, ptr
+  // X86F128: store fp128 pinf, ptr
+  // PPCF128: store fp128 pinf, ptr
   *l = __builtin_infl();
 
   // F80: call x86_fp80 @ldexpl(x86_fp80 noundef %{{.+}}, i32 noundef %{{.+}})
diff --git a/clang/test/CodeGen/mips-unsupported-nan.c b/clang/test/CodeGen/mips-unsupported-nan.c
index 16cea3c2e7e182..b2d08104d76f06 100644
--- a/clang/test/CodeGen/mips-unsupported-nan.c
+++ b/clang/test/CodeGen/mips-unsupported-nan.c
@@ -45,7 +45,7 @@
 // In regular (2008) mode, the quiet bit is set to indicate QNAN.
 
 // CHECK-NANLEGACY: double 0x7FF4000000000000
-// CHECK-NAN2008: double 0x7FF8000000000000
+// CHECK-NAN2008: double nan
 
 double d =  __builtin_nan("");
 
@@ -54,6 +54,6 @@ double d =  __builtin_nan("");
 // quiet bit on conversion independently of the setting in clang.
 
 // CHECK-NANLEGACY: float 0x7FFC000000000000
-// CHECK-NAN2008: float 0x7FF8000000000000
+// CHECK-NAN2008: float nan
 
 float f =  __builtin_nan("");
diff --git a/clang/test/CodeGen/strictfp_builtins.c b/clang/test/CodeGen/strictfp_builtins.c
index 58815c7de4fa94..b66983af4457c5 100644
--- a/clang/test/CodeGen/strictfp_builtins.c
+++ b/clang/test/CodeGen/strictfp_builtins.c
@@ -42,7 +42,7 @@ void p(char *str, int x) {
 // CHECK-NEXT:    br i1 [[CMP]], label [[FPCLASSIFY_END]], label [[FPCLASSIFY_NOT_NAN]]
 // CHECK:       fpclassify_not_nan:
 // CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[TMP0]]) #[[ATTR5:[0-9]+]]
-// CHECK-NEXT:    [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR4]]
+// CHECK-NEXT:    [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double pinf, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR4]]
 // CHECK-NEXT:    br i1 [[ISINF]], label [[FPCLASSIFY_END]], label [[FPCLASSIFY_NOT_INF]]
 // CHECK:       fpclassify_not_inf:
 // CHECK-NEXT:    [[ISNORMAL:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x10000000000000, metadata !"uge", metadata !"fpexcept.strict") #[[ATTR4]]
@@ -157,7 +157,7 @@ void test_double_isfinite(double d) {
 // CHECK-NEXT:    store double [[D:%.*]], ptr [[D_ADDR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load double, ptr [[D_ADDR]], align 8
 // CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[TMP0]]) #[[ATTR5]]
-// CHECK-NEXT:    [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR4]]
+// CHECK-NEXT:    [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double pinf, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR4]]
 // CHECK-NEXT:    [[TMP2:%.*]] = bitcast double [[TMP0]] to i64
 // CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 0
 // CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 -1, i32 1
diff --git a/clang/test/Headers/cuda_wrapper_algorithm.cu b/clang/test/Headers/cuda_wrapper_algorithm.cu
index d514285f7e17bb..45fa408814c72e 100644
--- a/clang/test/Headers/cuda_wrapper_algorithm.cu
+++ b/clang/test/Headers/cuda_wrapper_algorithm.cu
@@ -16,7 +16,7 @@ extern "C" bool cmp(double a, double b) { return a<b; }
 
 // CHECK-LABEL: @test_std_min(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    ret double 0x7FF8000000000000
+// CHECK-NEXT:    ret double nan
 //
 extern "C" double test_std_min() {
   return std::min(__builtin_nan(""), 0.0);
@@ -24,7 +24,7 @@ extern "C" double test_std_min() {
 
 // CHECK-LABEL: @test_std_min_cmp(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    ret double 0x7FF8000000000000
+// CHECK-NEXT:    ret double nan
 //
 extern "C" double test_std_min_cmp() {
   return std::min(__builtin_nan(""), 0.0, cmp);
@@ -32,7 +32,7 @@ extern "C" double test_std_min_cmp() {
 
 // CHECK-LABEL: @test_std_max(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    ret double 0x7FF8000000000000
+// CHECK-NEXT:    ret double nan
 //
 extern "C" double test_std_max() {
   return std::max(__builtin_nan(""), 0.0);
@@ -40,7 +40,7 @@ extern "C" double test_std_max() {
 
 // CHECK-LABEL: @test_std_max_cmp(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    ret double 0x7FF8000000000000
+// CHECK-NEXT:    ret double nan
 //
 extern "C" double test_std_max_cmp() {
   return std::max(__builtin_nan(""), 0.0, cmp);
diff --git a/clang/test/Lexer/11-27-2007-FloatLiterals.c b/clang/test/Lexer/11-27-2007-FloatLiterals.c
index f3d978b06925cd..2033c87a0a2a1b 100644
--- a/clang/test/Lexer/11-27-2007-FloatLiterals.c
+++ b/clang/test/Lexer/11-27-2007-FloatLiterals.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -mllvm -force-print-hex-special-fp -o - | FileCheck %s
 
 // CHECK: 0x3BFD83C940000000
 // CHECK: 2.000000e+{{[0]*}}32
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 0ee4d7b444cfcf..1bcc8089326ac1 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -4387,12 +4387,12 @@ Simple Constants
     zeros. So '``s0x0001``' of type '``i16``' will be -1, not 1.
 **Floating-point constants**
     Floating-point constants use standard decimal notation (e.g.
-    123.421), exponential notation (e.g. 1.23421e+2), or a more precise
-    hexadecimal notation (see below). The assembler requires the exact
-    decimal value of a floating-point constant. For example, the
-    assembler accepts 1.25 but rejects 1.3 because 1.3 is a repeating
-    decimal in binary. Floating-point constants must have a
-    :ref:`floating-point <t_floating>` type.
+    123.421), exponential notation (e.g. 1.23421e+2), identifiers for special
+    values like ``nan``, or a more precise hexadecimal notation (see below).
+    The assembler requires the exact decimal value of a floating-point
+    constant. For example, the assembler accepts 1.25 but rejects 1.3
+    because 1.3 is a repeating decimal in binary. Floating-point constants
+    must have a :ref:`floating-point <t_floating>` type.
 **Null pointer constants**
     The identifier '``null``' is recognized as a null pointer constant
     and must be of :ref:`pointer type <t_pointer>`.
@@ -4403,13 +4403,12 @@ Simple Constants
 The one non-intuitive notation for constants is the hexadecimal form of
 floating-point constants. For example, the form
 '``double    0x432ff973cafa8000``' is equivalent to (but harder to read
-than) '``double 4.5e+15``'. The only time hexadecimal floating-point
-constants are required (and the only time that they are generated by the
-disassembler) is when a floating-point constant must be emitted but it
+than) '``double 4.5e+15``'. Hexadecimal floating-point
+constants are used when a floating-point constant must be emitted but it
 cannot be represented as a decimal floating-point number in a reasonable
 number of digits. For example, NaN's, infinities, and other special
-values are represented in their IEEE hexadecimal format so that assembly
-and disassembly do not cause any bits to change in the constants.
+values are represented in their IEEE hexadecimal format. This ensures that
+assembly and disassembly do not cause any bits to change in the constants.
 
 When using the hexadecimal form, constants of types bfloat, half, float, and
 double are represented using the 16-digit form shown above (which matches the
@@ -4426,6 +4425,32 @@ represented by ``0xH`` followed by 4 hexadecimal digits. The bfloat 16-bit
 format is represented by ``0xR`` followed by 4 hexadecimal digits. All
 hexadecimal formats are big-endian (sign bit at the left).
 
+Some of the special floating point values can be represented by the following
+identifiers:
+
+    +-------------------+---------------------------------------------------+
+    | Name              | Description                                       |
+    +===================+===================================================+
+    | ``nan``           | Positive quiet NaN w/ payload equal to zero       |
+    +-------------------+---------------------------------------------------+
+    | ``qnan(payload)`` | Positive quiet NaN w/ custom payload              |
+    +-------------------+---------------------------------------------------+
+    | ``snan(payload)`` | Positive signaling NaN w/ custom payload          |
+    +-------------------+---------------------------------------------------+
+    | ``pinf``          | Positive infinity                                 |
+    +-------------------+---------------------------------------------------+
+    | ``ninf``          | Negative infinity                                 |
+    +-------------------+---------------------------------------------------+
+
+Please be careful when specifying the payload of ``snan`` and ``qnan``: the parser
+always uses a ``double`` to carry floating point constants before converting it to
+the target type. In some conversion cases, converting to ``float`` for instance,
+it "truncates" the significand bits (where the payloads are stored) from LSB
+rather than MSB. And if this conversion leads to any precision lost, it throws
+an error. For example, a value like ``float qnan(12)`` will give you an error
+because the lower 29 bits are lost after conversion and the new payload is now
+zero, which is considered a precision lost.
+
 There are no constants of type x86_amx.
 
 .. _complexconstants:
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index f41907f0351257..925794ae07e646 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3833,6 +3833,40 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
   case lltok::kw_poison: ID.Kind = ValID::t_Poison; break;
   case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break;
   case lltok::kw_none: ID.Kind = ValID::t_None; break;
+  case lltok::kw_nan:
+    ID.APFloatVal = APFloat::getQNaN(APFloat::IEEEdouble());
+    ID.Kind = ValID::t_APFloat;
+    break;
+  case lltok::kw_qnan:
+  case lltok::kw_snan: {
+    bool IsSignaling = Lex.getKind() == lltok::kw_snan;
+    Lex.Lex();
+    if (parseToken(lltok::lparen, "expected '('") ||
+        (Lex.getKind() != lltok::APSInt &&
+         tokError("expected an integer as payload")))
+      return true;
+    const APSInt &Payload = Lex.getAPSIntVal();
+    if (IsSignaling) {
+      if (Payload.isZero())
+        return tokError("expec...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/105618


More information about the cfe-commits mailing list