From 3ffb751f3dbf059b2ec061fe2f4302c9eba26b43 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 15 Aug 2020 14:21:24 -0400 Subject: [PATCH] [InstCombine] fold copysign with fabs/fneg operand We already get this in the backend, but we need to do it in IR too to consistently get yet more copysign transforms. --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 6 ++++++ llvm/test/Transforms/InstCombine/copysign.ll | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 864a5f4..6a188f6 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1221,6 +1221,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { if (match(Sign, m_Intrinsic(m_Value(), m_Value(X)))) return replaceOperand(*II, 1, X); + // Peek through changes of magnitude's sign-bit. This call rewrites those: + // copysign (fabs X), Sign --> copysign X, Sign + // copysign (fneg X), Sign --> copysign X, Sign + if (match(Mag, m_FAbs(m_Value(X))) || match(Mag, m_FNeg(m_Value(X)))) + return replaceOperand(*II, 0, X); + break; } case Intrinsic::fabs: { diff --git a/llvm/test/Transforms/InstCombine/copysign.ll b/llvm/test/Transforms/InstCombine/copysign.ll index f278be71..1a8910b 100644 --- a/llvm/test/Transforms/InstCombine/copysign.ll +++ b/llvm/test/Transforms/InstCombine/copysign.ll @@ -92,8 +92,7 @@ define float @copysign_sign_arg(float %x, float %y, float %z) { define float @fneg_mag(float %x, float %y) { ; CHECK-LABEL: @fneg_mag( -; CHECK-NEXT: [[N:%.*]] = fneg float [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[N]], float [[Y:%.*]]) +; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]]) ; CHECK-NEXT: ret float [[R]] ; %n = fneg float %x @@ -103,8 +102,7 @@ define float @fneg_mag(float %x, float %y) { define float @fabs_mag(float %x, float %y) { ; CHECK-LABEL: @fabs_mag( -; CHECK-NEXT: [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) -; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[A]], float [[Y:%.*]]) +; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]]) ; CHECK-NEXT: ret float [[R]] ; %a = call float @llvm.fabs.f32(float %x) -- 2.7.4