https://github.com/arsenm updated
https://github.com/llvm/llvm-project/pull/74056
>From 9be777d5b39852cf3c0b2538fd5f712922672caa Mon Sep 17 00:00:00 2001
From: Matt Arsenault
Date: Fri, 1 Dec 2023 18:00:13 +0900
Subject: [PATCH] Reapply "InstCombine: Introduce SimplifyDemandedUseFPClass""
This reverts commit ef388334ee5a3584255b9ef5b3fefdb244fa3fd7.
The referenced issue violates the spec for finite-only math only by
using a return value for a constant infinity.
---
clang/test/Headers/__clang_hip_math.hip | 56 +++--
llvm/include/llvm/Analysis/ValueTracking.h| 4 +
.../InstCombine/InstCombineInternal.h | 9 +
.../InstCombineSimplifyDemanded.cpp | 140 +++-
.../InstCombine/InstructionCombining.cpp | 18 +-
.../InstCombine/simplify-demanded-fpclass.ll | 203 +++---
6 files changed, 286 insertions(+), 144 deletions(-)
diff --git a/clang/test/Headers/__clang_hip_math.hip
b/clang/test/Headers/__clang_hip_math.hip
index c0f4a06acbb8e3..9e15aec94dc28a 100644
--- a/clang/test/Headers/__clang_hip_math.hip
+++ b/clang/test/Headers/__clang_hip_math.hip
@@ -2557,33 +2557,65 @@ extern "C" __device__ double test_nan(const char *tag) {
return nan(tag);
}
-// CHECK-LABEL: @test_nanf_emptystr(
-// CHECK-NEXT: entry:
-// CHECK-NEXT:ret float 0x7FF8
+// DEFAULT-LABEL: @test_nanf_emptystr(
+// DEFAULT-NEXT: entry:
+// DEFAULT-NEXT:ret float 0x7FF8
+//
+// FINITEONLY-LABEL: @test_nanf_emptystr(
+// FINITEONLY-NEXT: entry:
+// FINITEONLY-NEXT:ret float poison
+//
+// APPROX-LABEL: @test_nanf_emptystr(
+// APPROX-NEXT: entry:
+// APPROX-NEXT:ret float 0x7FF8
//
extern "C" __device__ float test_nanf_emptystr() {
return nanf("");
}
-// CHECK-LABEL: @test_nan_emptystr(
-// CHECK-NEXT: entry:
-// CHECK-NEXT:ret double 0x7FF8
+// DEFAULT-LABEL: @test_nan_emptystr(
+// DEFAULT-NEXT: entry:
+// DEFAULT-NEXT:ret double 0x7FF8
+//
+// FINITEONLY-LABEL: @test_nan_emptystr(
+// FINITEONLY-NEXT: entry:
+// FINITEONLY-NEXT:ret double poison
+//
+// APPROX-LABEL: @test_nan_emptystr(
+// APPROX-NEXT: entry:
+// APPROX-NEXT:ret double 0x7FF8
//
extern "C" __device__ double test_nan_emptystr() {
return nan("");
}
-// CHECK-LABEL: @test_nanf_fill(
-// CHECK-NEXT: entry:
-// CHECK-NEXT:ret float 0x7FF8
+// DEFAULT-LABEL: @test_nanf_fill(
+// DEFAULT-NEXT: entry:
+// DEFAULT-NEXT:ret float 0x7FF8
+//
+// FINITEONLY-LABEL: @test_nanf_fill(
+// FINITEONLY-NEXT: entry:
+// FINITEONLY-NEXT:ret float poison
+//
+// APPROX-LABEL: @test_nanf_fill(
+// APPROX-NEXT: entry:
+// APPROX-NEXT:ret float 0x7FF8
//
extern "C" __device__ float test_nanf_fill() {
return nanf("0x456");
}
-// CHECK-LABEL: @test_nan_fill(
-// CHECK-NEXT: entry:
-// CHECK-NEXT:ret double 0x7FF8
+// DEFAULT-LABEL: @test_nan_fill(
+// DEFAULT-NEXT: entry:
+// DEFAULT-NEXT:ret double 0x7FF8
+//
+// FINITEONLY-LABEL: @test_nan_fill(
+// FINITEONLY-NEXT: entry:
+// FINITEONLY-NEXT:ret double poison
+//
+// APPROX-LABEL: @test_nan_fill(
+// APPROX-NEXT: entry:
+// APPROX-NEXT:ret double 0x7FF8
//
extern "C" __device__ double test_nan_fill() {
return nan("0x123");
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h
b/llvm/include/llvm/Analysis/ValueTracking.h
index 82c87edd6297cd..f9ce679bc74268 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -243,6 +243,10 @@ struct KnownFPClass {
/// definitely set or false if the sign bit is definitely unset.
std::optional SignBit;
+ bool operator==(KnownFPClass Other) const {
+return KnownFPClasses == Other.KnownFPClasses && SignBit == Other.SignBit;
+ }
+
/// Return true if it's known this can never be one of the mask entries.
bool isKnownNever(FPClassTest Mask) const {
return (KnownFPClasses & Mask) == fcNone;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 0bbb22be71569f..9a66fb8f456f95 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -551,6 +551,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
APInt &UndefElts, unsigned Depth = 0,
bool AllowMultipleUsers = false) override;
+ /// Attempts to replace V with a simpler value based on the demanded
+ /// floating-point classes
+ Value *SimplifyDemandedUseFPClass(Value *V, FPClassTest DemandedMask,
+KnownFPClass &Known, unsigned Depth,
+Instruction *CxtI);
+ bool SimplifyDemandedFPClass(Instruction *I, unsigned Op,
+ FPClassTest DemandedMask, KnownFPCl