[llvm-branch-commits] [llvm] b845f06 - [ValueTracking] Fix computeKnownFPClass for fpext (#81972)
Tom Stellard via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 19 16:37:56 PST 2024
Author: Yingwei Zheng
Date: 2024-02-19T16:36:53-08:00
New Revision: b845f0662a287912332c89e56f5900037aa7c70f
URL: https://github.com/llvm/llvm-project/commit/b845f0662a287912332c89e56f5900037aa7c70f
DIFF: https://github.com/llvm/llvm-project/commit/b845f0662a287912332c89e56f5900037aa7c70f.diff
LOG: [ValueTracking] Fix computeKnownFPClass for fpext (#81972)
This patch adds the missing `subnormal -> normal` part for `fpext` in
`computeKnownFPClass`.
Fixes the miscompilation reported by
https://github.com/llvm/llvm-project/pull/80941#issuecomment-1947302100.
(cherry picked from commit a5865c3c3dbbd17ae12ecc1c297fe1fc2605df52)
Added:
llvm/test/Transforms/InstCombine/pr80941.ll
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/Attributor/nofpclass-fpext.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5d6c3465a0c364..412115eb649c2f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5083,8 +5083,13 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Op->getOperand(0)->getType()->getScalarType()->getFltSemantics();
// All subnormal inputs should be in the normal range in the result type.
- if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy))
+ if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
+ if (Known.KnownFPClasses & fcPosSubnormal)
+ Known.KnownFPClasses |= fcPosNormal;
+ if (Known.KnownFPClasses & fcNegSubnormal)
+ Known.KnownFPClasses |= fcNegNormal;
Known.knownNot(fcSubnormal);
+ }
// Sign bit of a nan isn't guaranteed.
if (!Known.isKnownNeverNaN())
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fpext.ll b/llvm/test/Transforms/Attributor/nofpclass-fpext.ll
index 0ba114117ceec6..ee36f949529d4f 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fpext.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fpext.ll
@@ -142,7 +142,7 @@ define double @ret_fpext_f32_to_f64_nosub(float nofpclass(sub) %arg0) {
}
define double @ret_fpext_f32_to_f64_nonorm(float nofpclass(norm) %arg0) {
-; CHECK-LABEL: define nofpclass(sub norm) double @ret_fpext_f32_to_f64_nonorm
+; CHECK-LABEL: define nofpclass(sub) double @ret_fpext_f32_to_f64_nonorm
; CHECK-SAME: (float nofpclass(sub norm) [[ARG0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[EXT:%.*]] = fpext float [[ARG0]] to double
; CHECK-NEXT: ret double [[EXT]]
@@ -482,7 +482,37 @@ define double @ret_fpext_bf16_f64_nosub(bfloat nofpclass(sub) %arg0) {
}
define double @ret_fpext_bf16_f64_nonorm(bfloat nofpclass(norm) %arg0) {
-; CHECK-LABEL: define nofpclass(sub norm) double @ret_fpext_bf16_f64_nonorm
+; CHECK-LABEL: define nofpclass(sub) double @ret_fpext_bf16_f64_nonorm
+; CHECK-SAME: (bfloat nofpclass(sub norm) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[EXT:%.*]] = fpext bfloat [[ARG0]] to double
+; CHECK-NEXT: ret double [[EXT]]
+;
+ %ext = fpext bfloat %arg0 to double
+ ret double %ext
+}
+
+define double @ret_fpext_bf16_f64_nonorm_psub(bfloat nofpclass(norm psub) %arg0) {
+; CHECK-LABEL: define nofpclass(sub pnorm) double @ret_fpext_bf16_f64_nonorm_psub
+; CHECK-SAME: (bfloat nofpclass(sub norm) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[EXT:%.*]] = fpext bfloat [[ARG0]] to double
+; CHECK-NEXT: ret double [[EXT]]
+;
+ %ext = fpext bfloat %arg0 to double
+ ret double %ext
+}
+
+define double @ret_fpext_bf16_f64_nonorm_nsub(bfloat nofpclass(norm nsub) %arg0) {
+; CHECK-LABEL: define nofpclass(sub nnorm) double @ret_fpext_bf16_f64_nonorm_nsub
+; CHECK-SAME: (bfloat nofpclass(sub norm) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[EXT:%.*]] = fpext bfloat [[ARG0]] to double
+; CHECK-NEXT: ret double [[EXT]]
+;
+ %ext = fpext bfloat %arg0 to double
+ ret double %ext
+}
+
+define double @ret_fpext_bf16_f64_nonorm_sub(bfloat nofpclass(norm sub) %arg0) {
+; CHECK-LABEL: define nofpclass(sub norm) double @ret_fpext_bf16_f64_nonorm_sub
; CHECK-SAME: (bfloat nofpclass(sub norm) [[ARG0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[EXT:%.*]] = fpext bfloat [[ARG0]] to double
; CHECK-NEXT: ret double [[EXT]]
diff --git a/llvm/test/Transforms/InstCombine/pr80941.ll b/llvm/test/Transforms/InstCombine/pr80941.ll
new file mode 100644
index 00000000000000..95242b1d1407bf
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/pr80941.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+define float @pr80941(float %arg) {
+; CHECK-LABEL: define float @pr80941(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[COND:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 144)
+; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_EXIT:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: [[FPEXT:%.*]] = fpext float [[ARG]] to double
+; CHECK-NEXT: [[SIGN:%.*]] = call double @llvm.copysign.f64(double 0.000000e+00, double [[FPEXT]])
+; CHECK-NEXT: [[FPTRUNC:%.*]] = fptrunc double [[SIGN]] to float
+; CHECK-NEXT: br label [[IF_EXIT]]
+; CHECK: if.exit:
+; CHECK-NEXT: [[RET:%.*]] = phi float [ [[FPTRUNC]], [[IF_THEN]] ], [ [[ARG]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: ret float [[RET]]
+;
+entry:
+ %cond = tail call i1 @llvm.is.fpclass.f32(float %arg, i32 144)
+ br i1 %cond, label %if.then, label %if.exit
+
+if.then:
+ %fpext = fpext float %arg to double
+ %sign = call double @llvm.copysign.f64(double 0.000000e+00, double %fpext)
+ %fptrunc = fptrunc double %sign to float
+ br label %if.exit
+
+if.exit:
+ %ret = phi float [ %fptrunc, %if.then ], [ %arg, %entry ]
+ ret float %ret
+}
More information about the llvm-branch-commits
mailing list