[PATCH] D87197: [InstSimplify] Fold degenerate abs of abs form

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 5 12:54:19 PDT 2020


nikic created this revision.
nikic added reviewers: spatel, lebedev.ri.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
nikic requested review of this revision.

This addresses the remaining issue from D87188 <https://reviews.llvm.org/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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87197

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


Index: llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
+++ llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
@@ -205,10 +205,7 @@
 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_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 @@
 ; 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 @@
 ; 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
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3965,6 +3965,15 @@
     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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87197.290107.patch
Type: text/x-patch
Size: 3057 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200905/051511b2/attachment.bin>


More information about the llvm-commits mailing list