forked from OSchip/llvm-project
[Thumb1] combine ADDC/SUBC with a negative immediate
Summary: This simple optimization has been split out of https://reviews.llvm.org/D30400 Reviewers: efriedma, jmolloy Subscribers: llvm-commits, rengolin Differential Revision: https://reviews.llvm.org/D30829 llvm-svn: 297682
This commit is contained in:
parent
987a281afe
commit
bf19d4bc29
|
@ -9660,6 +9660,24 @@ static SDValue PerformUMLALCombine(SDNode *N, SelectionDAG &DAG,
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDValue PerformAddcSubcCombine(SDNode *N, SelectionDAG &DAG,
|
||||||
|
const ARMSubtarget *Subtarget) {
|
||||||
|
if (Subtarget->isThumb1Only()) {
|
||||||
|
SDValue RHS = N->getOperand(1);
|
||||||
|
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {
|
||||||
|
int64_t imm = C->getSExtValue();
|
||||||
|
if (imm < 0) {
|
||||||
|
SDLoc DL(N);
|
||||||
|
RHS = DAG.getConstant(-imm, DL, MVT::i32);
|
||||||
|
unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
|
||||||
|
: ARMISD::ADDC;
|
||||||
|
return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
static SDValue PerformAddeSubeCombine(SDNode *N, SelectionDAG &DAG,
|
static SDValue PerformAddeSubeCombine(SDNode *N, SelectionDAG &DAG,
|
||||||
const ARMSubtarget *Subtarget) {
|
const ARMSubtarget *Subtarget) {
|
||||||
if (Subtarget->isThumb1Only()) {
|
if (Subtarget->isThumb1Only()) {
|
||||||
|
@ -11729,6 +11747,8 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
|
||||||
case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
|
case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
|
||||||
case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
|
case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
|
||||||
case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
|
case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
|
||||||
|
case ARMISD::ADDC:
|
||||||
|
case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI.DAG, Subtarget);
|
||||||
case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI.DAG, Subtarget);
|
case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI.DAG, Subtarget);
|
||||||
case ARMISD::BFI: return PerformBFICombine(N, DCI);
|
case ARMISD::BFI: return PerformBFICombine(N, DCI);
|
||||||
case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
|
case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
|
||||||
|
|
|
@ -1453,12 +1453,6 @@ def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8),
|
||||||
def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
|
def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
|
||||||
(tCMPr tGPR:$Rn, tGPR:$Rm)>;
|
(tCMPr tGPR:$Rn, tGPR:$Rm)>;
|
||||||
|
|
||||||
// Subtract with carry
|
|
||||||
def : T1Pat<(ARMaddc tGPR:$lhs, imm0_7_neg:$rhs),
|
|
||||||
(tSUBSi3 tGPR:$lhs, imm0_7_neg:$rhs)>;
|
|
||||||
def : T1Pat<(ARMaddc tGPR:$lhs, imm8_255_neg:$rhs),
|
|
||||||
(tSUBSi8 tGPR:$lhs, imm8_255_neg:$rhs)>;
|
|
||||||
|
|
||||||
// Bswap 16 with load/store
|
// Bswap 16 with load/store
|
||||||
def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)),
|
def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)),
|
||||||
(tREV16 (tLDRHi t_addrmode_is2:$addr))>;
|
(tREV16 (tLDRHi t_addrmode_is2:$addr))>;
|
||||||
|
|
|
@ -132,8 +132,7 @@ entry:
|
||||||
; CHECK: sbcs r1, r2
|
; CHECK: sbcs r1, r2
|
||||||
}
|
}
|
||||||
|
|
||||||
define i64 @f9d(i64 %x, i32 %y) { ; SUBS with small negative imm => SUBS reg
|
define i64 @f9d(i64 %x, i32 %y) { ; SUBS with small negative imm => ADDS imm
|
||||||
; FIXME: this would be better lowered as an `ADDS imm`
|
|
||||||
entry:
|
entry:
|
||||||
%conv = sext i32 %y to i64
|
%conv = sext i32 %y to i64
|
||||||
%shl = shl i64 %conv, 32
|
%shl = shl i64 %conv, 32
|
||||||
|
@ -141,9 +140,7 @@ entry:
|
||||||
%sub = sub nsw i64 %x, %or
|
%sub = sub nsw i64 %x, %or
|
||||||
ret i64 %sub
|
ret i64 %sub
|
||||||
; CHECK-LABEL: f9d:
|
; CHECK-LABEL: f9d:
|
||||||
; CHECK: movs r3, #0
|
; CHECK: adds r0, r0, #1
|
||||||
; CHECK: mvns r3, r3
|
|
||||||
; CHECK: subs r0, r0, r3
|
|
||||||
; CHECK: sbcs r1, r2
|
; CHECK: sbcs r1, r2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,11 +184,12 @@ entry:
|
||||||
%tmp2 = add i64 %tmp1, -1000
|
%tmp2 = add i64 %tmp1, -1000
|
||||||
ret i64 %tmp2
|
ret i64 %tmp2
|
||||||
; CHECK-LABEL: f11:
|
; CHECK-LABEL: f11:
|
||||||
|
; CHECK: movs r0, #125
|
||||||
|
; CHECK: lsls r0, r0, #3
|
||||||
; CHECK: movs r1, #0
|
; CHECK: movs r1, #0
|
||||||
; CHECK: ldr r0,
|
; CHECK: subs r2, r2, r0
|
||||||
; CHECK: adds r2, r2, r0
|
|
||||||
; CHECK: sbcs r3, r1
|
; CHECK: sbcs r3, r1
|
||||||
; CHECK: adds r0, r2, r0
|
; CHECK: subs r0, r2, r0
|
||||||
; CHECK: sbcs r3, r1
|
; CHECK: sbcs r3, r1
|
||||||
; CHECK: movs r1, r3
|
; CHECK: movs r1, r3
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue