Skip to content

Commit 44b7da8

Browse files
committed
[InstCombine] fmul nnan X, 0.0 --> copysign(0.0, X)
https://alive2.llvm.org/ce/z/ybgM5F Differential Revision: https://reviews.llvm.org/D136166
1 parent d169896 commit 44b7da8

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,13 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
521521
if (match(Op1, m_SpecificFP(-1.0)))
522522
return UnaryOperator::CreateFNegFMF(Op0, &I);
523523

524+
// With no-nans: X * 0.0 --> copysign(0.0, X)
525+
if (I.hasNoNaNs() && match(Op1, m_PosZeroFP())) {
526+
CallInst *CopySign = Builder.CreateIntrinsic(Intrinsic::copysign,
527+
{I.getType()}, {Op1, Op0}, &I);
528+
return replaceInstUsesWith(I, CopySign);
529+
}
530+
524531
// -X * C --> X * -C
525532
Value *X, *Y;
526533
Constant *C;

llvm/test/Transforms/InstCombine/fmul.ll

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,22 +1203,26 @@ define <vscale x 2 x float> @mul_scalable_splat_zero(<vscale x 2 x float> %z) {
12031203

12041204
define half @mul_zero_nnan(half %x) {
12051205
; CHECK-LABEL: @mul_zero_nnan(
1206-
; CHECK-NEXT: [[R:%.*]] = fmul nnan half [[X:%.*]], 0xH0000
1207-
; CHECK-NEXT: ret half [[R]]
1206+
; CHECK-NEXT: [[TMP1:%.*]] = call nnan half @llvm.copysign.f16(half 0xH0000, half [[X:%.*]])
1207+
; CHECK-NEXT: ret half [[TMP1]]
12081208
;
12091209
%r = fmul nnan half %x, 0.0
12101210
ret half %r
12111211
}
12121212

1213+
; poison propagates through vector elements
1214+
12131215
define <2 x float> @mul_zero_nnan_vec_poison(<2 x float> %x) {
12141216
; CHECK-LABEL: @mul_zero_nnan_vec_poison(
1215-
; CHECK-NEXT: [[R:%.*]] = fmul nnan <2 x float> [[X:%.*]], <float 0.000000e+00, float poison>
1216-
; CHECK-NEXT: ret <2 x float> [[R]]
1217+
; CHECK-NEXT: [[TMP1:%.*]] = call nnan <2 x float> @llvm.copysign.v2f32(<2 x float> <float 0.000000e+00, float poison>, <2 x float> [[X:%.*]])
1218+
; CHECK-NEXT: ret <2 x float> [[TMP1]]
12171219
;
12181220
%r = fmul nnan <2 x float> %x, <float 0.0, float poison>
12191221
ret <2 x float> %r
12201222
}
12211223

1224+
; negative test - must have nnan
1225+
12221226
define half @mul_zero(half %x) {
12231227
; CHECK-LABEL: @mul_zero(
12241228
; CHECK-NEXT: [[R:%.*]] = fmul ninf nsz half [[X:%.*]], 0xH0000
@@ -1228,6 +1232,8 @@ define half @mul_zero(half %x) {
12281232
ret half %r
12291233
}
12301234

1235+
; TODO: This could be fneg+copysign.
1236+
12311237
define half @mul_negzero_nnan(half %x) {
12321238
; CHECK-LABEL: @mul_negzero_nnan(
12331239
; CHECK-NEXT: [[R:%.*]] = fmul nnan half [[X:%.*]], 0xH8000

0 commit comments

Comments
 (0)