[llvm] ff218cb - [InstSimplify] Fold degenerate abs of abs form

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 6 00:45:05 PDT 2020


Author: Nikita Popov
Date: 2020-09-06T09:43:08+02:00
New Revision: ff218cbc84ff3783cb5ad030397adef8c9e8d444

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

LOG: [InstSimplify] Fold degenerate abs of abs form

This addresses the remaining issue from D87188. Due to a series of
folds, we may end up with abs-of-abs represented as
x == 0 ? -abs(x) : abs(x). Rather than recognizing this as a special
abs pattern and doing an abs-of-abs fold on it afterwards,
I'm directly folding this to one of the select operands in InstSimplify.

The general pattern falls into the "select with operand replaced"
category, but that fold is not powerful enough to recognize that
both hands of the select are the same for value zero.

Differential Revision: https://reviews.llvm.org/D87197

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/abs_intrinsic.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 3139b5a96b27..7c13b41bc7e6 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3965,6 +3965,15 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
     if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&
         Pred == ICmpInst::ICMP_EQ)
       return FalseVal;
+
+    // X == 0 ? abs(X) : -abs(X) --> -abs(X)
+    // X == 0 ? -abs(X) : abs(X) --> abs(X)
+    if (match(TrueVal, m_Intrinsic<Intrinsic::abs>(m_Value(X))) &&
+        match(FalseVal, m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(X)))))
+      return FalseVal;
+    if (match(TrueVal, m_Neg(m_Intrinsic<Intrinsic::abs>(m_Value(X)))) &&
+        match(FalseVal, m_Intrinsic<Intrinsic::abs>(m_Specific(X))))
+      return FalseVal;
   }
 
   // Check for other compares that behave like bit test.

diff  --git a/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll b/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
index e9305a927c42..70b50da9f041 100644
--- a/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
+++ b/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
@@ -205,10 +205,7 @@ define i1 @abs_ule_int_min(i8 %x) {
 define i32 @select_abs_of_abs_eq(i32 %x) {
 ; CHECK-LABEL: @select_abs_of_abs_eq(
 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
-; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[ABS]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[ABS]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ABS]]
 ;
   %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
   %neg = sub i32 0, %abs
@@ -220,10 +217,7 @@ define i32 @select_abs_of_abs_eq(i32 %x) {
 define i32 @select_abs_of_abs_ne(i32 %x) {
 ; CHECK-LABEL: @select_abs_of_abs_ne(
 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
-; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[ABS]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[ABS]], i32 [[NEG]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ABS]]
 ;
   %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
   %neg = sub i32 0, %abs
@@ -236,9 +230,7 @@ define i32 @select_nabs_of_abs_eq(i32 %x) {
 ; CHECK-LABEL: @select_nabs_of_abs_eq(
 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
 ; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[ABS]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[ABS]], i32 [[NEG]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[NEG]]
 ;
   %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
   %neg = sub i32 0, %abs
@@ -251,9 +243,7 @@ define i32 @select_nabs_of_abs_ne(i32 %x) {
 ; CHECK-LABEL: @select_nabs_of_abs_ne(
 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
 ; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[ABS]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[ABS]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[NEG]]
 ;
   %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
   %neg = sub i32 0, %abs


        


More information about the llvm-commits mailing list