[llvm] [PowerPC] Require PPC32 for 32-bit addc/adde/subc/sube (PR #179186)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 2 01:14:53 PST 2026
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/179186
Unlike the base add/sub opcodes which will just overflow, these will produce incorrect results, because the carry operates on the full 64-bits. Trying to use these with i32 operands on PPC64 should result in a selection failure instead of a silent miscompile, like the one seen in https://github.com/llvm/llvm-project/pull/178979.
>From 823315d927f7141b8e3349f8fd1a579899a3777e Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 2 Feb 2026 10:08:19 +0100
Subject: [PATCH] [PowerPC] Require PPC32 for 32-bit addc/adde/subc/sube
---
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 27 ++++++++++++++++---------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 88dd4df7e4366..6b04cd377e00a 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2556,7 +2556,7 @@ let Defs = [CARRY] in
def ADDIC : DForm_2<12, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
"addic $RST, $RA, $D", IIC_IntGeneral,
[(set i32:$RST, (PPCaddc i32:$RA, imm32SExt16:$D))]>,
- RecFormRel, PPC970_DGroup_Cracked;
+ RecFormRel, PPC970_DGroup_Cracked, Requires<[IsPPC32]>;
let Defs = [CARRY, CR0] in
def ADDIC_rec : DForm_2<13, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
"addic. $RST, $RA, $D", IIC_IntGeneral,
@@ -2576,7 +2576,8 @@ def MULLI : DForm_2< 7, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
let Defs = [CARRY] in
def SUBFIC : DForm_2< 8, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
"subfic $RST, $RA, $D", IIC_IntGeneral,
- [(set i32:$RST, (PPCsubc imm32SExt16:$D, i32:$RA))]>;
+ [(set i32:$RST, (PPCsubc imm32SExt16:$D, i32:$RA))]>,
+ Requires<[IsPPC32]>;
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
def LI : DForm_2_r0<14, (outs gprc:$RST), (ins s16imm:$D),
@@ -3175,7 +3176,7 @@ let isCommutable = 1 in
defm ADDC : XOForm_1rc<31, 10, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
"addc", "$RT, $RA, $RB", IIC_IntGeneral,
[(set i32:$RT, (PPCaddc i32:$RA, i32:$RB))]>,
- PPC970_DGroup_Cracked;
+ PPC970_DGroup_Cracked, Requires<[IsPPC32]>;
defm DIVW : XOForm_1rcr<31, 491, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
"divw", "$RT, $RA, $RB", IIC_IntDivW,
@@ -3208,7 +3209,7 @@ defm SUBF : XOForm_1rx<31, 40, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
defm SUBFC : XOForm_1rc<31, 8, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
"subfc", "$RT, $RA, $RB", IIC_IntGeneral,
[(set i32:$RT, (PPCsubc i32:$RB, i32:$RA))]>,
- PPC970_DGroup_Cracked;
+ PPC970_DGroup_Cracked, Requires<[IsPPC32]>;
defm NEG : XOForm_3r<31, 104, 0, (outs gprc:$RT), (ins gprc:$RA),
"neg", "$RT, $RA", IIC_IntSimple,
[(set i32:$RT, (ineg i32:$RA))]>;
@@ -3216,22 +3217,28 @@ let Uses = [CARRY] in {
let isCommutable = 1 in
defm ADDE : XOForm_1rc<31, 138, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
"adde", "$RT, $RA, $RB", IIC_IntGeneral,
- [(set i32:$RT, (PPCadde i32:$RA, i32:$RB, CARRY))]>;
+ [(set i32:$RT, (PPCadde i32:$RA, i32:$RB, CARRY))]>,
+ Requires<[IsPPC32]>;
defm ADDME : XOForm_3rc<31, 234, 0, (outs gprc:$RT), (ins gprc:$RA),
"addme", "$RT, $RA", IIC_IntGeneral,
- [(set i32:$RT, (PPCadde i32:$RA, -1, CARRY))]>;
+ [(set i32:$RT, (PPCadde i32:$RA, -1, CARRY))]>,
+ Requires<[IsPPC32]>;
defm ADDZE : XOForm_3rc<31, 202, 0, (outs gprc:$RT), (ins gprc:$RA),
"addze", "$RT, $RA", IIC_IntGeneral,
- [(set i32:$RT, (PPCadde i32:$RA, 0, CARRY))]>;
+ [(set i32:$RT, (PPCadde i32:$RA, 0, CARRY))]>,
+ Requires<[IsPPC32]>;
defm SUBFE : XOForm_1rc<31, 136, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
"subfe", "$RT, $RA, $RB", IIC_IntGeneral,
- [(set i32:$RT, (PPCsube i32:$RB, i32:$RA, CARRY))]>;
+ [(set i32:$RT, (PPCsube i32:$RB, i32:$RA, CARRY))]>,
+ Requires<[IsPPC32]>;
defm SUBFME : XOForm_3rc<31, 232, 0, (outs gprc:$RT), (ins gprc:$RA),
"subfme", "$RT, $RA", IIC_IntGeneral,
- [(set i32:$RT, (PPCsube -1, i32:$RA, CARRY))]>;
+ [(set i32:$RT, (PPCsube -1, i32:$RA, CARRY))]>,
+ Requires<[IsPPC32]>;
defm SUBFZE : XOForm_3rc<31, 200, 0, (outs gprc:$RT), (ins gprc:$RA),
"subfze", "$RT, $RA", IIC_IntGeneral,
- [(set i32:$RT, (PPCsube 0, i32:$RA, CARRY))]>;
+ [(set i32:$RT, (PPCsube 0, i32:$RA, CARRY))]>,
+ Requires<[IsPPC32]>;
}
}
More information about the llvm-commits
mailing list