[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