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
