llvm.org GIT mirror llvm / bc4037e
[DAG] Promote ADDCARRY / SUBCARRY Add missing case that was not implemented yet. Differential Revision: https://reviews.llvm.org/D38942 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320567 91177308-0d34-0410-b5e6-96231b3b80d8 Roger Ferrer Ibanez 2 years ago
2 changed file(s) with 84 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
771771 SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBCARRY(SDNode *N, unsigned ResNo) {
772772 if (ResNo == 1)
773773 return PromoteIntRes_Overflow(N);
774 llvm_unreachable("Not implemented");
774
775 // We need to sign-extend the operands so the carry value computed by the
776 // wide operation will be equivalent to the carry value computed by the
777 // narrow operation.
778 // An ADDCARRY can generate carry only if any of the operands has its
779 // most significant bit set. Sign extension propagates the most significant
780 // bit into the higher bits which means the extra bit that the narrow
781 // addition would need (i.e. the carry) will be propagated through the higher
782 // bits of the wide addition.
783 // A SUBCARRY can generate borrow only if LHS < RHS and this property will be
784 // preserved by sign extension.
785 SDValue LHS = SExtPromotedInteger(N->getOperand(0));
786 SDValue RHS = SExtPromotedInteger(N->getOperand(1));
787
788 EVT ValueVTs[] = {LHS.getValueType(), N->getValueType(1)};
789
790 // Do the arithmetic in the wide type.
791 SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N), DAG.getVTList(ValueVTs),
792 LHS, RHS, N->getOperand(2));
793
794 // Update the users of the original carry/borrow value.
795 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
796
797 return SDValue(Res.getNode(), 0);
775798 }
776799
777800 SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
0 ; RUN: llc -O2 -mtriple armv7a < %s | FileCheck --check-prefix=ARM %s
1
2 ; RUN: llc -O2 -mtriple thumbv6m < %s | FileCheck --check-prefix=THUMB1 %s
3 ; RUN: llc -O2 -mtriple thumbv8m.base < %s | FileCheck --check-prefix=THUMB1 %s
4
5 ; RUN: llc -O2 -mtriple thumbv7a < %s | FileCheck --check-prefix=THUMB %s
6 ; RUN: llc -O2 -mtriple thumbv8m.main < %s | FileCheck --check-prefix=THUMB %s
7
8 define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
9 entry:
10
11 ; ARM: rsb r2, r2, #1
12 ; ARM: adds r0, r1, r0
13 ; ARM: movw r1, #65535
14 ; ARM: sxth r2, r2
15 ; ARM: adc r0, r2, #0
16 ; ARM: tst r0, r1
17 ; ARM: bxeq lr
18 ; ARM: .LBB0_1:
19 ; ARM: b .LBB0_1
20
21 ; THUMB1: movs r3, #1
22 ; THUMB1: subs r2, r3, r2
23 ; THUMB1: sxth r2, r2
24 ; THUMB1: movs r3, #0
25 ; THUMB1: adds r0, r1, r0
26 ; THUMB1: adcs r3, r2
27 ; THUMB1: lsls r0, r3, #16
28 ; THUMB1: beq .LBB0_2
29 ; THUMB1: .LBB0_1:
30 ; THUMB1: b .LBB0_1
31
32 ; THUMB: rsb.w r2, r2, #1
33 ; THUMB: adds r0, r0, r1
34 ; THUMB: sxth r2, r2
35 ; THUMB: adc r0, r2, #0
36 ; THUMB: lsls r0, r0, #16
37 ; THUMB: it eq
38 ; THUMB: bxeq lr
39 ; THUMB: .LBB0_1:
40 ; THUMB: b .LBB0_1
41
42 %add = add i32 %b, %a
43 %cmp = icmp ult i32 %add, %b
44 %conv = zext i1 %cmp to i32
45 %sub = sub i32 1, %c
46 %add1 = add i32 %sub, %conv
47 %conv2 = trunc i32 %add1 to i16
48 %tobool = icmp eq i16 %conv2, 0
49 br i1 %tobool, label %if.end, label %for.cond.preheader
50
51 for.cond.preheader: ; preds = %entry
52 br label %for.cond
53
54 for.cond: ; preds = %for.cond.preheader, %for.cond
55 br label %for.cond
56
57 if.end: ; preds = %entry
58 ret void
59 }