mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-20 05:38:50 +00:00
Fix ARM isle code that optimize multiply by constants which are power-of-2 +/- 1.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76520 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c95be59371
commit
af9e7a7c20
@ -949,26 +949,36 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
|||||||
unsigned RHSV = C->getZExtValue();
|
unsigned RHSV = C->getZExtValue();
|
||||||
if (!RHSV) break;
|
if (!RHSV) break;
|
||||||
if (isPowerOf2_32(RHSV-1)) { // 2^n+1?
|
if (isPowerOf2_32(RHSV-1)) { // 2^n+1?
|
||||||
|
unsigned ShImm = Log2_32(RHSV-1);
|
||||||
|
if (ShImm >= 32)
|
||||||
|
break;
|
||||||
SDValue V = Op.getOperand(0);
|
SDValue V = Op.getOperand(0);
|
||||||
unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
|
ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm);
|
||||||
SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
|
SDValue ShImmOp = CurDAG->getConstant(ShImm, MVT::i32);
|
||||||
CurDAG->getTargetConstant(ShImm, MVT::i32),
|
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
|
||||||
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
|
if (Subtarget->isThumb() && Subtarget->hasThumb2()) {
|
||||||
CurDAG->getRegister(0, MVT::i32) };
|
SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
|
||||||
return CurDAG->SelectNodeTo(N, (Subtarget->isThumb() &&
|
return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6);
|
||||||
Subtarget->hasThumb2()) ?
|
} else {
|
||||||
ARM::t2ADDrs : ARM::ADDrs, MVT::i32, Ops, 7);
|
SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
|
||||||
|
return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isPowerOf2_32(RHSV+1)) { // 2^n-1?
|
if (isPowerOf2_32(RHSV+1)) { // 2^n-1?
|
||||||
|
unsigned ShImm = Log2_32(RHSV+1);
|
||||||
|
if (ShImm >= 32)
|
||||||
|
break;
|
||||||
SDValue V = Op.getOperand(0);
|
SDValue V = Op.getOperand(0);
|
||||||
unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1));
|
ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm);
|
||||||
SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
|
SDValue ShImmOp = CurDAG->getConstant(ShImm, MVT::i32);
|
||||||
CurDAG->getTargetConstant(ShImm, MVT::i32),
|
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
|
||||||
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
|
if (Subtarget->isThumb() && Subtarget->hasThumb2()) {
|
||||||
CurDAG->getRegister(0, MVT::i32) };
|
SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0 };
|
||||||
return CurDAG->SelectNodeTo(N, (Subtarget->isThumb() &&
|
return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 5);
|
||||||
Subtarget->hasThumb2()) ?
|
} else {
|
||||||
ARM::t2RSBrs : ARM::RSBrs, MVT::i32, Ops, 7);
|
SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
|
||||||
|
return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
17
test/CodeGen/ARM/mul_const.ll
Normal file
17
test/CodeGen/ARM/mul_const.ll
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=arm | FileCheck %s
|
||||||
|
|
||||||
|
define i32 @t1(i32 %v) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: t1:
|
||||||
|
; CHECK: add r0, r0, r0, lsl #3
|
||||||
|
%0 = mul i32 %v, 9
|
||||||
|
ret i32 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @t2(i32 %v) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: t2:
|
||||||
|
; CHECK: rsb r0, r0, r0, lsl #3
|
||||||
|
%0 = mul i32 %v, 7
|
||||||
|
ret i32 %0
|
||||||
|
}
|
18
test/CodeGen/Thumb2/mul_const.ll
Normal file
18
test/CodeGen/Thumb2/mul_const.ll
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | FileCheck %s
|
||||||
|
; rdar://7069502
|
||||||
|
|
||||||
|
define i32 @t1(i32 %v) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: t1:
|
||||||
|
; CHECK: add r0, r0, r0, lsl #3
|
||||||
|
%0 = mul i32 %v, 9
|
||||||
|
ret i32 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @t2(i32 %v) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: t2:
|
||||||
|
; CHECK: rsb r0, r0, r0, lsl #3
|
||||||
|
%0 = mul i32 %v, 7
|
||||||
|
ret i32 %0
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user