[llvm] 4164741 - [PowerPC] Fix an LowerADDSUBO_CARRY error when converting carry bit for usubo_carry (#137809)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 30 07:39:12 PDT 2025


Author: zhijian lin
Date: 2025-04-30T10:39:09-04:00
New Revision: 41647412c6a4091080fd47b0f554adc5c54b4b54

URL: https://github.com/llvm/llvm-project/commit/41647412c6a4091080fd47b0f554adc5c54b4b54
DIFF: https://github.com/llvm/llvm-project/commit/41647412c6a4091080fd47b0f554adc5c54b4b54.diff

LOG: [PowerPC] Fix an LowerADDSUBO_CARRY error when converting carry bit for usubo_carry (#137809)

In PowerPC, if a borrow occurs during a subtraction, the carry bit is
zero (unset). The carry bit is set if no borrow occurs.

For ISD::USUBO_CARRY, the nodes produce two results: the normal result
of the addition or subtraction, and a boolean value that is 1 if and
only if there is an outgoing carry or borrow.

Therefore, we need to convert a 1 (which indicates a borrow in
ISD::USUBO_CARRY) to 0 to match PowerPC's definition of borrow.
Similarly, we need to convert a 0 (no borrow in ISD::USUBO_CARRY) to 1
for PowerPC.

To perform this conversion, we use XOR 1 instead of XOR
DAG.getAllOnesConstant(DL, CarryOp.getValueType()).

`

Added: 
    llvm/test/CodeGen/PowerPC/usubo_carry.ll

Modified: 
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 64f61fe7852ed..f9e791e4b34f8 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -12323,7 +12323,7 @@ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
   Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
   if (!IsAdd)
     CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
-                          DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
+                          DAG.getConstant(1UL, DL, CarryOp.getValueType()));
   CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
   SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
                             Op.getOperand(0), Op.getOperand(1), CarryOp);

diff  --git a/llvm/test/CodeGen/PowerPC/usubo_carry.ll b/llvm/test/CodeGen/PowerPC/usubo_carry.ll
new file mode 100644
index 0000000000000..3f6ec7520cd58
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/usubo_carry.ll
@@ -0,0 +1,32 @@
+; RUN: llc -ppc-asm-full-reg-names -verify-machineinstrs \
+; RUN:   -mtriple=powerpc-ibm-aix -mcpu=pwr7 < %s | FileCheck %s
+
+define i64 @foo(i32 noundef %argc) #0 {
+entry:
+  %argc.addr = alloca i32, align 4
+  %num = alloca i64, align 8
+  store i32 %argc, ptr %argc.addr, align 4
+  %0 = load i32, ptr %argc.addr, align 4
+  %sub = sub nsw i32 %0, 2
+  %conv = sext i32 %sub to i64
+  store i64 %conv, ptr %num, align 8
+  %1 = load i64, ptr %num, align 8
+  %sub1 = sub nsw i64 0, %1
+  ret i64 %sub1
+}
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all"  "stack-protector-buffer-size"="8" }
+
+; CHECK:      .foo:
+; CHECK-NEXT: # %bb.0:                                # %entry
+; CHECK-NEXT:   stw r3, -8(r1)
+; CHECK-NEXT:   lwz r3, -8(r1)
+; CHECK-NEXT:   addi r3, r3, -2
+; CHECK-NEXT:   srawi r4, r3, 31
+; CHECK-NEXT:   stw r3, -12(r1)
+; CHECK-NEXT:   stw r4, -16(r1)
+; CHECK-NEXT:   lwz r3, -16(r1)
+; CHECK-NEXT:   lwz r4, -12(r1)
+; CHECK-NEXT:   subfic r4, r4, 0
+; CHECK-NEXT:   subfze r3, r3
+; CHECK-NEXT:   blr


        


More information about the llvm-commits mailing list