[llvm] 139da9c - [InstCombine] fold fabs of select with negated operand

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 06:23:28 PDT 2020


Author: Sanjay Patel
Date: 2020-08-18T09:23:07-04:00
New Revision: 139da9c4d74391cd9d12600650ef95d5d68d8b59

URL: https://github.com/llvm/llvm-project/commit/139da9c4d74391cd9d12600650ef95d5d68d8b59
DIFF: https://github.com/llvm/llvm-project/commit/139da9c4d74391cd9d12600650ef95d5d68d8b59.diff

LOG: [InstCombine] fold fabs of select with negated operand

This is the FP example shown in:
https://bugs.llvm.org/PR39474

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/test/Transforms/InstCombine/fabs.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 6a188f6a4da4..fa9c6e184e38 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1230,13 +1230,21 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     break;
   }
   case Intrinsic::fabs: {
-    Value *Cond;
-    Constant *LHS, *RHS;
+    Value *Cond, *TVal, *FVal;
     if (match(II->getArgOperand(0),
-              m_Select(m_Value(Cond), m_Constant(LHS), m_Constant(RHS)))) {
-      CallInst *Call0 = Builder.CreateCall(II->getCalledFunction(), {LHS});
-      CallInst *Call1 = Builder.CreateCall(II->getCalledFunction(), {RHS});
-      return SelectInst::Create(Cond, Call0, Call1);
+              m_Select(m_Value(Cond), m_Value(TVal), m_Value(FVal)))) {
+      // fabs (select Cond, TrueC, FalseC) --> select Cond, AbsT, AbsF
+      if (isa<Constant>(TVal) && isa<Constant>(FVal)) {
+        CallInst *AbsT = Builder.CreateCall(II->getCalledFunction(), {TVal});
+        CallInst *AbsF = Builder.CreateCall(II->getCalledFunction(), {FVal});
+        return SelectInst::Create(Cond, AbsT, AbsF);
+      }
+      // fabs (select Cond, -FVal, FVal) --> fabs FVal
+      if (match(TVal, m_FNeg(m_Specific(FVal))))
+        return replaceOperand(*II, 0, FVal);
+      // fabs (select Cond, TVal, -TVal) --> fabs TVal
+      if (match(FVal, m_FNeg(m_Specific(TVal))))
+        return replaceOperand(*II, 0, TVal);
     }
 
     LLVM_FALLTHROUGH;

diff  --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll
index c0d2c3b701f0..f8b70afea380 100644
--- a/llvm/test/Transforms/InstCombine/fabs.ll
+++ b/llvm/test/Transforms/InstCombine/fabs.ll
@@ -751,9 +751,7 @@ define half @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(half %x) {
 
 define float @select_fneg(i1 %c, float %x) {
 ; CHECK-LABEL: @select_fneg(
-; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], float [[N]], float [[X]]
-; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[S]])
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
 ; CHECK-NEXT:    ret float [[FABS]]
 ;
   %n = fneg float %x
@@ -766,8 +764,7 @@ define float @select_fneg_use1(i1 %c, float %x) {
 ; CHECK-LABEL: @select_fneg_use1(
 ; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[N]])
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], float [[X]], float [[N]]
-; CHECK-NEXT:    [[FABS:%.*]] = call fast float @llvm.fabs.f32(float [[S]])
+; CHECK-NEXT:    [[FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
 ; CHECK-NEXT:    ret float [[FABS]]
 ;
   %n = fneg float %x
@@ -782,7 +779,7 @@ define float @select_fneg_use2(i1 %c, float %x) {
 ; CHECK-NEXT:    [[N:%.*]] = fneg arcp float [[X:%.*]]
 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], float [[N]], float [[X]]
 ; CHECK-NEXT:    call void @use(float [[S]])
-; CHECK-NEXT:    [[FABS:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[S]])
+; CHECK-NEXT:    [[FABS:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X]])
 ; CHECK-NEXT:    ret float [[FABS]]
 ;
   %n = fneg arcp float %x
@@ -794,9 +791,7 @@ define float @select_fneg_use2(i1 %c, float %x) {
 
 define <2 x float> @select_fneg_vec(<2 x i1> %c, <2 x float> %x) {
 ; CHECK-LABEL: @select_fneg_vec(
-; CHECK-NEXT:    [[N:%.*]] = fneg <2 x float> [[X:%.*]]
-; CHECK-NEXT:    [[S:%.*]] = select fast <2 x i1> [[C:%.*]], <2 x float> [[X]], <2 x float> [[N]]
-; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[S]])
+; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
 ;
   %n = fneg <2 x float> %x


        


More information about the llvm-commits mailing list