-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SimplifyLibCalls] Constant fold nan libcall #101459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesReference: https://en.cppreference.com/w/c/numeric/math/nan llvm-project/clang/lib/AST/ExprConstant.cpp Lines 14741 to 14777 in 1d2b2d2
Full diff: https://github.com/llvm/llvm-project/pull/101459.diff 5 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 4100471eaaa1d..948e510be5c32 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3858,6 +3858,22 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
return nullptr;
}
+/// Constant folding nan/nanf/nanl.
+static Value *optimizeNaN(CallInst *CI) {
+ StringRef CharSeq;
+ if (!getConstantStringInfo(CI->getArgOperand(0), CharSeq))
+ return nullptr;
+
+ llvm::APInt Fill;
+ // Treat empty strings as if they were zero.
+ if (CharSeq.empty())
+ Fill = llvm::APInt(32, 0);
+ else if (CharSeq.getAsInteger(0, Fill))
+ return nullptr;
+
+ return ConstantFP::getQNaN(CI->getType(), /*Negative=*/false, &Fill);
+}
+
Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
LibFunc Func,
IRBuilderBase &Builder) {
@@ -3972,6 +3988,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
case LibFunc_remquof:
case LibFunc_remquol:
return optimizeRemquo(CI, Builder);
+ case LibFunc_nan:
+ case LibFunc_nanf:
+ case LibFunc_nanl:
+ return optimizeNaN(CI);
default:
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/nan.ll b/llvm/test/Transforms/InstCombine/nan.ll
new file mode 100644
index 0000000000000..fd4119bc0c06a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/nan.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+@empty = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+@dec = private unnamed_addr constant [2 x i8] c"1\00", align 1
+@hex = private unnamed_addr constant [4 x i8] c"0xf\00", align 1
+
+define double @nan_empty() {
+; CHECK-LABEL: define double @nan_empty() {
+; CHECK-NEXT: ret double 0x7FF8000000000000
+;
+ %res = call double @nan(ptr @empty)
+ ret double %res
+}
+
+define double @nan_dec() {
+; CHECK-LABEL: define double @nan_dec() {
+; CHECK-NEXT: ret double 0x7FF8000000000001
+;
+ %res = call double @nan(ptr @dec)
+ ret double %res
+}
+
+define double @nan_hex() {
+; CHECK-LABEL: define double @nan_hex() {
+; CHECK-NEXT: ret double 0x7FF800000000000F
+;
+ %res = call double @nan(ptr @hex)
+ ret double %res
+}
+
+define float @nanf_empty() {
+; CHECK-LABEL: define float @nanf_empty() {
+; CHECK-NEXT: ret float 0x7FF8000000000000
+;
+ %res = call float @nanf(ptr @empty)
+ ret float %res
+}
+
+declare float @nanf(ptr)
+declare double @nan(ptr)
diff --git a/llvm/test/Transforms/InstCombine/nanl-fp128.ll b/llvm/test/Transforms/InstCombine/nanl-fp128.ll
new file mode 100644
index 0000000000000..21ba0fb14ca20
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/nanl-fp128.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+@empty = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+@dec = private unnamed_addr constant [2 x i8] c"1\00", align 1
+@hex = private unnamed_addr constant [4 x i8] c"0xf\00", align 1
+
+define fp128 @nanl_empty() {
+; CHECK-LABEL: define fp128 @nanl_empty() {
+; CHECK-NEXT: ret fp128 0xL00000000000000007FFF800000000000
+;
+ %res = call fp128 @nanl(ptr @empty)
+ ret fp128 %res
+}
+
+define fp128 @nanl_dec() {
+; CHECK-LABEL: define fp128 @nanl_dec() {
+; CHECK-NEXT: ret fp128 0xL00000000000000017FFF800000000000
+;
+ %res = call fp128 @nanl(ptr @dec)
+ ret fp128 %res
+}
+
+define fp128 @nanl_hex() {
+; CHECK-LABEL: define fp128 @nanl_hex() {
+; CHECK-NEXT: ret fp128 0xL000000000000000F7FFF800000000000
+;
+ %res = call fp128 @nanl(ptr @hex)
+ ret fp128 %res
+}
+
+declare fp128 @nanl(ptr)
diff --git a/llvm/test/Transforms/InstCombine/nanl-fp80.ll b/llvm/test/Transforms/InstCombine/nanl-fp80.ll
new file mode 100644
index 0000000000000..7868af3696a56
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/nanl-fp80.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+@empty = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+@dec = private unnamed_addr constant [2 x i8] c"1\00", align 1
+@hex = private unnamed_addr constant [4 x i8] c"0xf\00", align 1
+
+define x86_fp80 @nanl_empty() {
+; CHECK-LABEL: define x86_fp80 @nanl_empty() {
+; CHECK-NEXT: ret x86_fp80 0xK7FFFC000000000000000
+;
+ %res = call x86_fp80 @nanl(ptr @empty)
+ ret x86_fp80 %res
+}
+
+define x86_fp80 @nanl_dec() {
+; CHECK-LABEL: define x86_fp80 @nanl_dec() {
+; CHECK-NEXT: ret x86_fp80 0xK7FFFC000000000000001
+;
+ %res = call x86_fp80 @nanl(ptr @dec)
+ ret x86_fp80 %res
+}
+
+define x86_fp80 @nanl_hex() {
+; CHECK-LABEL: define x86_fp80 @nanl_hex() {
+; CHECK-NEXT: ret x86_fp80 0xK7FFFC00000000000000F
+;
+ %res = call x86_fp80 @nanl(ptr @hex)
+ ret x86_fp80 %res
+}
+
+declare x86_fp80 @nanl(ptr)
diff --git a/llvm/test/Transforms/InstCombine/nanl-ppc-fp128.ll b/llvm/test/Transforms/InstCombine/nanl-ppc-fp128.ll
new file mode 100644
index 0000000000000..7f60a379c4885
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/nanl-ppc-fp128.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+@empty = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+@dec = private unnamed_addr constant [2 x i8] c"1\00", align 1
+@hex = private unnamed_addr constant [4 x i8] c"0xf\00", align 1
+
+define ppc_fp128 @nanl_empty() {
+; CHECK-LABEL: define ppc_fp128 @nanl_empty() {
+; CHECK-NEXT: ret ppc_fp128 0xM7FF80000000000000000000000000000
+;
+ %res = call ppc_fp128 @nanl(ptr @empty)
+ ret ppc_fp128 %res
+}
+
+define ppc_fp128 @nanl_dec() {
+; CHECK-LABEL: define ppc_fp128 @nanl_dec() {
+; CHECK-NEXT: ret ppc_fp128 0xM7FF80000000000010000000000000000
+;
+ %res = call ppc_fp128 @nanl(ptr @dec)
+ ret ppc_fp128 %res
+}
+
+define ppc_fp128 @nanl_hex() {
+; CHECK-LABEL: define ppc_fp128 @nanl_hex() {
+; CHECK-NEXT: ret ppc_fp128 0xM7FF800000000000F0000000000000000
+;
+ %res = call ppc_fp128 @nanl(ptr @hex)
+ ret ppc_fp128 %res
+}
+
+declare ppc_fp128 @nanl(ptr)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated, but in the attribute inference you could mark these returns as nofpclass(~nan)
Co-authored-by: Nikita Popov <[email protected]>
Reference: https://en.cppreference.com/w/c/numeric/math/nan
The logic is copied from clang frontend:
llvm-project/clang/lib/AST/ExprConstant.cpp
Lines 14741 to 14777 in 1d2b2d2