[llvm] [DAGCombiner] Fix abs(add) to abdu miscompile in foldABSToABD (PR #196782)

Iris Shi via llvm-commits llvm-commits at lists.llvm.org
Sat May 9 23:48:49 PDT 2026


https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196782

>From 4f02f9f3bc38d8b92e58a7f2578eccdebea2e712 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Sun, 10 May 2026 14:41:35 +0800
Subject: [PATCH 1/2] test

---
 llvm/test/CodeGen/X86/abds.ll | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/llvm/test/CodeGen/X86/abds.ll b/llvm/test/CodeGen/X86/abds.ll
index 5948af563d152..81683db82e9a5 100644
--- a/llvm/test/CodeGen/X86/abds.ll
+++ b/llvm/test/CodeGen/X86/abds.ll
@@ -1389,6 +1389,32 @@ define i32 @PR185467(i32 range(i32 0, 2147483647) %v) {
   ret i32 %absx
 }
 
+define i32 @abs_add_known_positive(i32 %a) {
+; X86-LABEL: abs_add_known_positive:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
+; X86-NEXT:    leal 1(%ecx), %edx
+; X86-NEXT:    movl $-1, %eax
+; X86-NEXT:    subl %ecx, %eax
+; X86-NEXT:    cmovbl %edx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: abs_add_known_positive:
+; X64:       # %bb.0:
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; X64-NEXT:    andl $2147483647, %edi # imm = 0x7FFFFFFF
+; X64-NEXT:    leal 1(%rdi), %ecx
+; X64-NEXT:    movl $-1, %eax
+; X64-NEXT:    subl %edi, %eax
+; X64-NEXT:    cmovbl %ecx, %eax
+; X64-NEXT:    retq
+  %x = and i32 %a, 2147483647
+  %add = add i32 %x, 1
+  %abs = call i32 @llvm.abs.i32(i32 %add, i1 false)
+  ret i32 %abs
+}
+
 declare i8 @llvm.abs.i8(i8, i1)
 declare i16 @llvm.abs.i16(i16, i1)
 declare i32 @llvm.abs.i32(i32, i1)

>From 2235483252ac30b4c7b71f221c609de095839005 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Sun, 10 May 2026 14:41:50 +0800
Subject: [PATCH 2/2] [DAGCombiner] Fix abs(add) to abdu miscompile in
 foldABSToABD

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  4 +--
 llvm/test/CodeGen/X86/abds.ll                 | 18 +++++-----
 shell.nix                                     | 34 +++++++++++++++++++
 3 files changed, 44 insertions(+), 12 deletions(-)
 create mode 100644 shell.nix

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5a467a5a5ba53..5dd025f1b42be 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12025,10 +12025,8 @@ SDValue DAGCombiner::foldABSToABD(SDNode *N, const SDLoc &DL) {
       return CreateZextedAbd(ISD::ABDS);
 
     // fold (abs (sub x, y)) -> abdu(x, y)
-    // fold (abs (add x, -y)) -> abdu(x, y)
     bool Op1SignBitIsOne = DAG.computeKnownBits(Op1).isNegative();
-    bool AbsOpWillNUW = DAG.SignBitIsZero(Op0) &&
-                        (IsAdd ? DAG.SignBitIsZero(Op1) : Op1SignBitIsOne);
+    bool AbsOpWillNUW = !IsAdd && DAG.SignBitIsZero(Op0) && Op1SignBitIsOne;
 
     if (hasOperation(ISD::ABDU, VT) && AbsOpWillNUW)
       return CreateZextedAbd(ISD::ABDU);
diff --git a/llvm/test/CodeGen/X86/abds.ll b/llvm/test/CodeGen/X86/abds.ll
index 81683db82e9a5..a3056e9426643 100644
--- a/llvm/test/CodeGen/X86/abds.ll
+++ b/llvm/test/CodeGen/X86/abds.ll
@@ -1392,12 +1392,12 @@ define i32 @PR185467(i32 range(i32 0, 2147483647) %v) {
 define i32 @abs_add_known_positive(i32 %a) {
 ; X86-LABEL: abs_add_known_positive:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
-; X86-NEXT:    leal 1(%ecx), %edx
-; X86-NEXT:    movl $-1, %eax
-; X86-NEXT:    subl %ecx, %eax
-; X86-NEXT:    cmovbl %edx, %eax
+; X86-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; X86-NEXT:    andl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    incl %ecx
+; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    negl %eax
+; X86-NEXT:    cmovsl %ecx, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: abs_add_known_positive:
@@ -1405,9 +1405,9 @@ define i32 @abs_add_known_positive(i32 %a) {
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    andl $2147483647, %edi # imm = 0x7FFFFFFF
 ; X64-NEXT:    leal 1(%rdi), %ecx
-; X64-NEXT:    movl $-1, %eax
-; X64-NEXT:    subl %edi, %eax
-; X64-NEXT:    cmovbl %ecx, %eax
+; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    negl %eax
+; X64-NEXT:    cmovsl %ecx, %eax
 ; X64-NEXT:    retq
   %x = and i32 %a, 2147483647
   %add = add i32 %x, 1
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000000000..7615218cfce56
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,34 @@
+with import <nixpkgs> {};
+let
+  gccForLibs = stdenv.cc.cc;
+in stdenv.mkDerivation {
+  name = "llvm-env";
+  buildInputs = [
+    python3
+    ninja
+    cmake
+    ccache
+  ];
+
+  shellHook = ''
+    configure() {
+      eval "cmake $cmakeFlags ../llvm $*"
+    }
+  '';
+
+  # where to find libgcc
+  NIX_LDFLAGS="-L${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}";
+  # teach clang about C startup file locations
+  CFLAGS="-B${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version} -B ${stdenv.cc.libc}/lib";
+
+  cmakeFlags = [
+    "-DC_INCLUDE_DIRS=${stdenv.cc.libc.dev}/include"
+    "-GNinja"
+    "-DCMAKE_BUILD_TYPE=Release"
+    "-DCMAKE_INSTALL_PREFIX=../inst"
+    "-DLLVM_ENABLE_PROJECTS=\"clang;llvm\""
+    "-DLLVM_TARGETS_TO_BUILD=host"
+    "-DCMAKE_C_COMPILER_LAUNCHER=ccache"
+    "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
+  ];
+}



More information about the llvm-commits mailing list