Skip to content

Commit 4164741

Browse files
authored
[PowerPC] Fix an LowerADDSUBO_CARRY error when converting carry bit for usubo_carry (llvm#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()). `
1 parent 84a5435 commit 4164741

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12323,7 +12323,7 @@ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
1232312323
Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
1232412324
if (!IsAdd)
1232512325
CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12326-
DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12326+
DAG.getConstant(1UL, DL, CarryOp.getValueType()));
1232712327
CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
1232812328
SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
1232912329
Op.getOperand(0), Op.getOperand(1), CarryOp);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: llc -ppc-asm-full-reg-names -verify-machineinstrs \
2+
; RUN: -mtriple=powerpc-ibm-aix -mcpu=pwr7 < %s | FileCheck %s
3+
4+
define i64 @foo(i32 noundef %argc) #0 {
5+
entry:
6+
%argc.addr = alloca i32, align 4
7+
%num = alloca i64, align 8
8+
store i32 %argc, ptr %argc.addr, align 4
9+
%0 = load i32, ptr %argc.addr, align 4
10+
%sub = sub nsw i32 %0, 2
11+
%conv = sext i32 %sub to i64
12+
store i64 %conv, ptr %num, align 8
13+
%1 = load i64, ptr %num, align 8
14+
%sub1 = sub nsw i64 0, %1
15+
ret i64 %sub1
16+
}
17+
18+
attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "stack-protector-buffer-size"="8" }
19+
20+
; CHECK: .foo:
21+
; CHECK-NEXT: # %bb.0: # %entry
22+
; CHECK-NEXT: stw r3, -8(r1)
23+
; CHECK-NEXT: lwz r3, -8(r1)
24+
; CHECK-NEXT: addi r3, r3, -2
25+
; CHECK-NEXT: srawi r4, r3, 31
26+
; CHECK-NEXT: stw r3, -12(r1)
27+
; CHECK-NEXT: stw r4, -16(r1)
28+
; CHECK-NEXT: lwz r3, -16(r1)
29+
; CHECK-NEXT: lwz r4, -12(r1)
30+
; CHECK-NEXT: subfic r4, r4, 0
31+
; CHECK-NEXT: subfze r3, r3
32+
; CHECK-NEXT: blr

0 commit comments

Comments
 (0)