https://github.com/llvmbot created 
https://github.com/llvm/llvm-project/pull/179181

Backport b4797d4

Requested by: @arsenm

>From a71240c6f8f336ba7749ee144a3fc6ff74170edf Mon Sep 17 00:00:00 2001
From: SiliconA-Z <[email protected]>
Date: Mon, 2 Feb 2026 03:00:40 -0500
Subject: [PATCH] [PowerPC] Fix miscompilation when using 32-bit ucmp on 64-bit
 PowerPC (#178979)

I forgot that you need to clear the upper 32 bits for the carry flag to
work properly on ppc64 or else there will be garbage and possibly
incorrect results.

Fixes: https://github.com/llvm/llvm-project/issues/179119

I do not have merge permissions.

(cherry picked from commit b4797d4c03b6efb624b8b3ba17a13a8c40b31d75)
---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 17 +++++++++++++----
 llvm/test/CodeGen/PowerPC/ucmp.ll           | 16 ++++++++++++----
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index ef211bf8c8982..640082153e57d 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -12574,10 +12574,19 @@ SDValue PPCTargetLowering::LowerUCMP(SDValue Op, 
SelectionDAG &DAG) const {
   SDLoc DL(Op);
   SDValue A = DAG.getFreeze(Op.getOperand(0));
   SDValue B = DAG.getFreeze(Op.getOperand(1));
-  EVT OpVT = A.getValueType();   // operand type
-  EVT ResVT = Op.getValueType(); // result type
+  EVT OpVT = A.getValueType();
+  EVT ResVT = Op.getValueType();
+
+  // On PPC64, i32 carries are affected by the upper 32 bits of the registers.
+  // We must zero-extend to i64 to ensure the carry reflects the 32-bit 
unsigned
+  // comparison.
+  if (Subtarget.isPPC64() && OpVT == MVT::i32) {
+    A = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, A);
+    B = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, B);
+    OpVT = MVT::i64;
+  }
 
-  // First compute diff = A - B (will become subf).
+  // First compute diff = A - B.
   SDValue Diff = DAG.getNode(ISD::SUB, DL, OpVT, A, B);
 
   // Generate B - A using SUBC to capture carry.
@@ -12592,7 +12601,7 @@ SDValue PPCTargetLowering::LowerUCMP(SDValue Op, 
SelectionDAG &DAG) const {
   // res = diff - t2 + CA1 using SUBE (produces desired -1/0/1).
   SDValue ResPair = DAG.getNode(PPCISD::SUBE, DL, VTs, Diff, SubE1, CA1);
 
-  // Extract the first result and truncate to result type if needed
+  // Extract the first result and truncate to result type if needed.
   return DAG.getSExtOrTrunc(ResPair.getValue(0), DL, ResVT);
 }
 
diff --git a/llvm/test/CodeGen/PowerPC/ucmp.ll 
b/llvm/test/CodeGen/PowerPC/ucmp.ll
index 4d393dd00e3db..6ece83c35e1fc 100644
--- a/llvm/test/CodeGen/PowerPC/ucmp.ll
+++ b/llvm/test/CodeGen/PowerPC/ucmp.ll
@@ -4,8 +4,10 @@
 define i8 @ucmp_8_8(i8 zeroext %x, i8 zeroext %y) nounwind {
 ; CHECK-LABEL: ucmp_8_8:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    subc 6, 4, 3
+; CHECK-NEXT:    clrldi 3, 3, 32
+; CHECK-NEXT:    clrldi 4, 4, 32
 ; CHECK-NEXT:    sub 5, 3, 4
+; CHECK-NEXT:    subc 6, 4, 3
 ; CHECK-NEXT:    subfe 3, 4, 3
 ; CHECK-NEXT:    subfe 3, 3, 5
 ; CHECK-NEXT:    blr
@@ -16,8 +18,10 @@ define i8 @ucmp_8_8(i8 zeroext %x, i8 zeroext %y) nounwind {
 define i8 @ucmp_8_16(i16 zeroext %x, i16 zeroext %y) nounwind {
 ; CHECK-LABEL: ucmp_8_16:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    subc 6, 4, 3
+; CHECK-NEXT:    clrldi 3, 3, 32
+; CHECK-NEXT:    clrldi 4, 4, 32
 ; CHECK-NEXT:    sub 5, 3, 4
+; CHECK-NEXT:    subc 6, 4, 3
 ; CHECK-NEXT:    subfe 3, 4, 3
 ; CHECK-NEXT:    subfe 3, 3, 5
 ; CHECK-NEXT:    blr
@@ -28,8 +32,10 @@ define i8 @ucmp_8_16(i16 zeroext %x, i16 zeroext %y) 
nounwind {
 define i8 @ucmp_8_32(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: ucmp_8_32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    subc 6, 4, 3
+; CHECK-NEXT:    clrldi 3, 3, 32
+; CHECK-NEXT:    clrldi 4, 4, 32
 ; CHECK-NEXT:    sub 5, 3, 4
+; CHECK-NEXT:    subc 6, 4, 3
 ; CHECK-NEXT:    subfe 3, 4, 3
 ; CHECK-NEXT:    subfe 3, 3, 5
 ; CHECK-NEXT:    blr
@@ -72,8 +78,10 @@ define i8 @ucmp_8_128(i128 %x, i128 %y) nounwind {
 define i32 @ucmp_32_32(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: ucmp_32_32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    subc 6, 4, 3
+; CHECK-NEXT:    clrldi 3, 3, 32
+; CHECK-NEXT:    clrldi 4, 4, 32
 ; CHECK-NEXT:    sub 5, 3, 4
+; CHECK-NEXT:    subc 6, 4, 3
 ; CHECK-NEXT:    subfe 3, 4, 3
 ; CHECK-NEXT:    subfe 3, 3, 5
 ; CHECK-NEXT:    blr

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to