Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 5 additions & 4 deletions llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1847,15 +1847,16 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
Value *X;
Instruction *Op = dyn_cast<Instruction>(FPT.getOperand(0));
if (Op && Op->hasOneUse()) {
// FIXME: The FMF should propagate from the fptrunc, not the source op.
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
FastMathFlags FMF = FPT.getFastMathFlags();
if (isa<FPMathOperator>(Op))
Builder.setFastMathFlags(Op->getFastMathFlags());
FMF &= Op->getFastMathFlags();
Copy link
Contributor

Choose a reason for hiding this comment

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

Description says union but this is intersection.Also dyn_cast to FPMathOperator and query flags from that, this is effectively isa + cast

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I meant intersection.

Builder.setFastMathFlags(FMF);

if (match(Op, m_FNeg(m_Value(X)))) {
Value *InnerTrunc = Builder.CreateFPTrunc(X, Ty);

return UnaryOperator::CreateFNegFMF(InnerTrunc, Op);
Value *Neg = Builder.CreateFNeg(InnerTrunc);
return replaceInstUsesWith(FPT, Neg);
}

// If we are truncating a select that has an extended operand, we can
Expand Down
55 changes: 55 additions & 0 deletions llvm/test/Transforms/InstCombine/fpcast.ll
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ define half @test3(float %a) {
ret half %c
}

define half @test3_fast(float %a) {
; CHECK-LABEL: @test3_fast(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = call half @llvm.fabs.f16(half [[TMP1]])
; CHECK-NEXT: ret half [[C]]
;
%b = call float @llvm.fabs.f32(float %a)
%c = fptrunc fast float %b to half
ret half %c
}

define half @fneg_fptrunc(float %a) {
; CHECK-LABEL: @fneg_fptrunc(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
Expand Down Expand Up @@ -78,6 +89,28 @@ define half @test4-fast(float %a) {
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc fast float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = fneg fast half [[TMP1]]
; CHECK-NEXT: ret half [[C]]
;
%b = fsub fast float -0.0, %a
%c = fptrunc fast float %b to half
ret half %c
}

define half @test4-mixed-fast-1(float %a) {
; CHECK-LABEL: @test4-mixed-fast-1(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]
; CHECK-NEXT: ret half [[C]]
;
%b = fsub float -0.0, %a
%c = fptrunc fast float %b to half
ret half %c
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Test a vector case, and with a subset of flags

define half @test4-mixed-fast-2(float %a) {
; CHECK-LABEL: @test4-mixed-fast-2(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]
; CHECK-NEXT: ret half [[C]]
;
%b = fsub fast float -0.0, %a
%c = fptrunc float %b to half
Expand All @@ -89,6 +122,28 @@ define half @test4_unary_fneg-fast(float %a) {
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc fast float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = fneg fast half [[TMP1]]
; CHECK-NEXT: ret half [[C]]
;
%b = fneg fast float %a
%c = fptrunc fast float %b to half
ret half %c
}

define half @test4_unary_fneg-mixed-fast-1(float %a) {
; CHECK-LABEL: @test4_unary_fneg-mixed-fast-1(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]
; CHECK-NEXT: ret half [[C]]
;
%b = fneg float %a
%c = fptrunc fast float %b to half
ret half %c
}

define half @test4_unary_fneg-mixed-fast-2(float %a) {
; CHECK-LABEL: @test4_unary_fneg-mixed-fast-2(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]
; CHECK-NEXT: ret half [[C]]
;
%b = fneg fast float %a
%c = fptrunc float %b to half
Expand Down
24 changes: 24 additions & 0 deletions llvm/test/Transforms/InstCombine/fptrunc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ define float @fptrunc_select_true_val(float %x, double %y, i1 %cond) {
ret float %r
}

define float @fptrunc_fast_select_true_val(float %x, double %y, i1 %cond) {
; CHECK-LABEL: @fptrunc_fast_select_true_val(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc fast double [[Y:%.*]] to float
; CHECK-NEXT: [[NARROW_SEL:%.*]] = select i1 [[COND:%.*]], float [[TMP1]], float [[X:%.*]]
; CHECK-NEXT: ret float [[NARROW_SEL]]
;
%e = fpext float %x to double
%sel = select fast i1 %cond, double %y, double %e
%r = fptrunc fast double %sel to float
ret float %r
}

define <2 x float> @fptrunc_select_false_val(<2 x float> %x, <2 x double> %y, <2 x i1> %cond) {
; CHECK-LABEL: @fptrunc_select_false_val(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x double> [[Y:%.*]] to <2 x float>
Expand All @@ -73,6 +85,18 @@ define <2 x float> @fptrunc_select_false_val(<2 x float> %x, <2 x double> %y, <2
ret <2 x float> %r
}

define <2 x float> @fptrunc_nnan_select_false_val(<2 x float> %x, <2 x double> %y, <2 x i1> %cond) {
; CHECK-LABEL: @fptrunc_nnan_select_false_val(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc nnan <2 x double> [[Y:%.*]] to <2 x float>
; CHECK-NEXT: [[NARROW_SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x float> [[TMP1]]
; CHECK-NEXT: ret <2 x float> [[NARROW_SEL]]
;
%e = fpext <2 x float> %x to <2 x double>
%sel = select nnan <2 x i1> %cond, <2 x double> %e, <2 x double> %y
%r = fptrunc nnan <2 x double> %sel to <2 x float>
ret <2 x float> %r
}

declare void @use(float)

define half @fptrunc_select_true_val_extra_use(half %x, float %y, i1 %cond) {
Expand Down
Loading