https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/217203
Backport 93030c3 Requested by: @Benjins >From f655a787ad37d1b5db9c739c1e2cca301f95aa0d Mon Sep 17 00:00:00 2001 From: Benji Smith <[email protected]> Date: Mon, 17 Aug 2026 21:54:01 -0400 Subject: [PATCH] [SDAG] Fix invalid sign bit condition for abs(sub) -> abdu fold (#215548) The fold here for (abs (sub x y)) -> (abdu x y) was proven in Alive, assuming that both operands had a sign bit of zero. However, the code was checking if x had a sign bit of zero and y had a sign bit of 1 Fixes https://github.com/llvm/llvm-project/issues/214942 Original Alive proof from https://github.com/llvm/llvm-project/pull/186659 : https://alive2.llvm.org/ce/z/HfPF5q A variant that's explicitly (abs (sub x y)): https://alive2.llvm.org/ce/z/QEgDaa And changing the range to 32770 or higher there will break the transformation (cherry picked from commit 93030c36edb97a9efeca32eea9a8ca0c27a6be1a) --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 +-- llvm/test/CodeGen/X86/abdu.ll | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 5fd1b10d97f35..67e16dcb41c7f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12126,8 +12126,8 @@ SDValue DAGCombiner::foldABSToABD(SDNode *N, const SDLoc &DL) { return CreateZextedAbd(ISD::ABDS); // fold (abs (sub x, y)) -> abdu(x, y) - bool Op1SignBitIsOne = DAG.computeKnownBits(Op1).isNegative(); - bool AbsOpWillNUW = !IsAdd && DAG.SignBitIsZero(Op0) && Op1SignBitIsOne; + bool AbsOpWillNUW = + !IsAdd && DAG.SignBitIsZero(Op0) && DAG.SignBitIsZero(Op1); if (hasOperation(ISD::ABDU, VT) && AbsOpWillNUW) return CreateZextedAbd(ISD::ABDU); diff --git a/llvm/test/CodeGen/X86/abdu.ll b/llvm/test/CodeGen/X86/abdu.ll index b8bc3649773f2..520a6917aff53 100644 --- a/llvm/test/CodeGen/X86/abdu.ll +++ b/llvm/test/CodeGen/X86/abdu.ll @@ -949,6 +949,36 @@ define i128 @abd_select_i128(i128 %a, i128 %b) nounwind { ret i128 %sub } +define i32 @abs_sub_abdu_sign_check(i32 %p0) { +; X86-LABEL: abs_sub_abdu_sign_check: +; X86: # %bb.0: # %entry +; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp) +; X86-NEXT: movl $1000000000, %eax # imm = 0x3B9ACA00 +; X86-NEXT: movl $-2039640824, %ecx # imm = 0x866D8D08 +; X86-NEXT: cmovel %eax, %ecx +; X86-NEXT: movl %ecx, %eax +; X86-NEXT: negl %eax +; X86-NEXT: cmovsl %ecx, %eax +; X86-NEXT: retl +; +; X64-LABEL: abs_sub_abdu_sign_check: +; X64: # %bb.0: # %entry +; X64-NEXT: testl %edi, %edi +; X64-NEXT: movl $1000000000, %eax # imm = 0x3B9ACA00 +; X64-NEXT: movl $-2039640824, %ecx # imm = 0x866D8D08 +; X64-NEXT: cmovel %eax, %ecx +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: negl %eax +; X64-NEXT: cmovsl %ecx, %eax +; X64-NEXT: retq +entry: + %cmp = icmp eq i32 %p0, 0 + %v = select i1 %cmp, i32 0, i32 1255326472 + %s = sub i32 %v, -1000000000 + %a = call i32 @llvm.abs.i32(i32 %s, i1 false) + ret i32 %a +} + declare i8 @llvm.abs.i8(i8, i1) declare i16 @llvm.abs.i16(i16, i1) declare i32 @llvm.abs.i32(i32, i1) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
