[llvm] [PowerPC] Fix crash when promoting smaller types to 64 bit ucmp (PR #203399)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 09:22:36 PDT 2026
https://github.com/mike-goutokuji updated https://github.com/llvm/llvm-project/pull/203399
>From 8975c1af654e819fa7818cf7e6e60e7c9cdaadc7 Mon Sep 17 00:00:00 2001
From: Mike-Goutokuji <83477269+mike-goutokuji at users.noreply.github.com>
Date: Thu, 11 Jun 2026 16:07:13 -0400
Subject: [PATCH] [PowerPC] Fix crash when promoting smaller types to 64 bit
ucmp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
i64 @llvm.ucmp(i8, …) bypasses UCMP i32→i64 promotion; widen operands in LowerUCMP before carry lowering.
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 11 ++++++++-
llvm/test/CodeGen/PowerPC/ucmp.ll | 27 +++++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index e43021b1f5379..eaf95cbd2d023 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -606,7 +606,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
// Custom handling for PowerPC ucmp instruction
if (isPPC64) {
// UCMP involves using carries, which only works in 64-bit
- setOperationAction(ISD::UCMP, MVT::i32, Promote);
+ setOperationPromotedToType(ISD::UCMP, MVT::i32, MVT::i64);
setOperationAction(ISD::UCMP, MVT::i64, Custom);
} else {
setOperationAction(ISD::UCMP, MVT::i32, Custom);
@@ -12802,6 +12802,15 @@ SDValue PPCTargetLowering::LowerUCMP(SDValue Op, SelectionDAG &DAG) const {
EVT OpVT = A.getValueType();
EVT ResVT = Op.getValueType();
+ // On PPC64, carry ops use the full 64-bit register. UCMP i32 is promoted to
+ // i64 by the legalizer; this only runs for UCMP i64 with operands still
+ // narrower than i64 (e.g. i64 @llvm.ucmp(i8, i8)).
+ if (Subtarget.isPPC64() && OpVT != MVT::i64) {
+ 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.
SDValue Diff = DAG.getNode(ISD::SUB, DL, OpVT, A, B);
diff --git a/llvm/test/CodeGen/PowerPC/ucmp.ll b/llvm/test/CodeGen/PowerPC/ucmp.ll
index e371776d82604..66387f979cae3 100644
--- a/llvm/test/CodeGen/PowerPC/ucmp.ll
+++ b/llvm/test/CodeGen/PowerPC/ucmp.ll
@@ -108,3 +108,30 @@ define i64 @ucmp_64_64(i64 %x, i64 %y) nounwind {
%1 = call i64 @llvm.ucmp(i64 %x, i64 %y)
ret i64 %1
}
+
+define i64 @ucmp_64_8_zero(i8 %x) nounwind {
+; CHECK-LABEL: ucmp_64_8_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: clrldi 3, 3, 56
+; CHECK-NEXT: subfic 4, 3, 0
+; CHECK-NEXT: li 4, 0
+; CHECK-NEXT: subfe 4, 4, 3
+; CHECK-NEXT: subfe 3, 4, 3
+; CHECK-NEXT: blr
+ %1 = call i64 @llvm.ucmp(i8 %x, i8 0)
+ ret i64 %1
+}
+
+define i64 @ucmp_64_8(i8 %x, i8 %y) nounwind {
+; CHECK-LABEL: ucmp_64_8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: clrldi 3, 3, 56
+; CHECK-NEXT: clrldi 4, 4, 56
+; 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
+ %1 = call i64 @llvm.ucmp(i8 %x, i8 %y)
+ ret i64 %1
+}
More information about the llvm-commits
mailing list