Skip to content
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

[ValueTracking] Fix computeKnownFPClass for fpext #81972

Merged
merged 2 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5173,8 +5173,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())
Expand Down
34 changes: 32 additions & 2 deletions llvm/test/Transforms/Attributor/nofpclass-fpext.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unfortunate that nofpclass is tested via Attributor, which means it can't be verified with alive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but alive never gets run (https://web.ist.utl.pt/nuno.lopes/alive2/index.php) on these tests because alive does not support inter-procedural passes like Attributor. As such, we don't automatically catch these issues even if they are completely obvious in existing tests.

; 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]]
Expand Down Expand Up @@ -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]]
Expand Down
32 changes: 32 additions & 0 deletions llvm/test/Transforms/InstCombine/pr80941.ll
Original file line number Diff line number Diff line change
@@ -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
}
Loading