[llvm] ff218cb - [InstSimplify] Fold degenerate abs of abs form
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 08:59:22 PDT 2020
Given:
x == 0 ? -abs(x) : Y
We should really be producing:
x == 0 ? 0 : Y
This seems like something CVP might be able to handle, or even an
alternate instcombine rule.
And once we have
x == 0 ? 0 : abs(x)
We should definitely fold that to abs(x).
Not suggesting that your change needs removed; just that there's an
alternate, slightly more general way of achieving the same thing.
Philip
On 9/6/20 12:45 AM, Nikita Popov via llvm-commits wrote:
> 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
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list