[llvm-commits] [llvm] r82948 - in /llvm/trunk: lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMInstrInfo.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/t2-imm.ll
Anton Korobeynikov
asl at math.spbu.ru
Sun Sep 27 16:52:58 PDT 2009
Author: asl
Date: Sun Sep 27 18:52:58 2009
New Revision: 82948
URL: http://llvm.org/viewvc/llvm-project?rev=82948&view=rev
Log:
Use movt/movw pair to materialize 32 bit constants on ARMv6T2+.
This should be better than single load from constpool.
Added:
llvm/trunk/test/CodeGen/ARM/t2-imm.ll
Modified:
llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=82948&r1=82947&r2=82948&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Sun Sep 27 18:52:58 2009
@@ -934,19 +934,21 @@
case ISD::Constant: {
unsigned Val = cast<ConstantSDNode>(N)->getZExtValue();
bool UseCP = true;
- if (Subtarget->isThumb()) {
- if (Subtarget->hasThumb2())
- // Thumb2 has the MOVT instruction, so all immediates can
- // be done with MOV + MOVT, at worst.
- UseCP = 0;
- else
+ if (Subtarget->hasThumb2())
+ // Thumb2-aware targets have the MOVT instruction, so all immediates can
+ // be done with MOV + MOVT, at worst.
+ UseCP = 0;
+ else {
+ if (Subtarget->isThumb()) {
UseCP = (Val > 255 && // MOV
~Val > 255 && // MOV + MVN
!ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL
- } else
- UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV
- ARM_AM::getSOImmVal(~Val) == -1 && // MVN
- !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs.
+ } else
+ UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV
+ ARM_AM::getSOImmVal(~Val) == -1 && // MVN
+ !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs.
+ }
+
if (UseCP) {
SDValue CPIdx =
CurDAG->getTargetConstantPool(ConstantInt::get(
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=82948&r1=82947&r2=82948&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Sun Sep 27 18:52:58 2009
@@ -96,6 +96,9 @@
MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
MI->getOperand(0).setReg(DestReg);
+ if (Orig->getOpcode() == ARM::MOVTi16)
+ MI->getOperand(1).setReg(DestReg);
+
MBB.insert(I, MI);
}
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=82948&r1=82947&r2=82948&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sun Sep 27 18:52:58 2009
@@ -190,6 +190,27 @@
let PrintMethod = "printBitfieldInvMaskImmOperand";
}
+/// Split a 32-bit immediate into two 16 bit parts.
+def lo16 : SDNodeXForm<imm, [{
+ return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
+ MVT::i32);
+}]>;
+
+def hi16 : SDNodeXForm<imm, [{
+ return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
+}]>;
+
+def lo16AllZero : PatLeaf<(i32 imm), [{
+ // Returns true if all low 16-bits are 0.
+ return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
+ }], hi16>;
+
+/// imm0_65535 predicate - True if the 32-bit immediate is in the range
+/// [0.65535].
+def imm0_65535 : PatLeaf<(i32 imm), [{
+ return (uint32_t)N->getZExtValue() < 65536;
+}]>;
+
class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
@@ -897,15 +918,36 @@
let neverHasSideEffects = 1 in
def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
- "mov", " $dst, $src", []>, UnaryDP;
+ "mov", " $dst, $src", []>, UnaryDP;
def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
- DPSoRegFrm, IIC_iMOVsr,
- "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
+ DPSoRegFrm, IIC_iMOVsr,
+ "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
- "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
- let Inst{25} = 1;
+ "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
+ let Inst{25} = 1;
+}
+
+let isReMaterializable = 1, isAsCheapAsAMove = 1 in
+def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
+ DPFrm, IIC_iMOVi,
+ "movw", " $dst, $src",
+ [(set GPR:$dst, imm0_65535:$src)]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{25} = 1;
+}
+
+let isReMaterializable = 1, isAsCheapAsAMove = 1,
+ Constraints = "$src = $dst" in
+def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
+ DPFrm, IIC_iMOVi,
+ "movt", " $dst, $imm",
+ [(set GPR:$dst,
+ (or (and GPR:$src, 0xffff),
+ lo16AllZero:$imm))]>, UnaryDP,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{25} = 1;
}
let Uses = [CPSR] in
@@ -1478,6 +1520,10 @@
(EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
(so_imm2part_2 imm:$RHS))>;
+def : ARMPat<(i32 imm:$src),
+ (MOVTi16 (MOVi16 (lo16 imm:$src)), (hi16 imm:$src))>,
+ Requires<[IsARM, HasV6T2]>;
+
// TODO: add,sub,and, 3-instr forms?
Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=82948&r1=82947&r2=82948&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Sun Sep 27 18:52:58 2009
@@ -88,28 +88,6 @@
return (uint32_t)(-N->getZExtValue()) < 255;
}], imm_neg_XFORM>;
-/// imm0_65535 predicate - True if the 32-bit immediate is in the range
-/// [0.65535].
-def imm0_65535 : PatLeaf<(i32 imm), [{
- return (uint32_t)N->getZExtValue() < 65536;
-}]>;
-
-/// Split a 32-bit immediate into two 16 bit parts.
-def t2_lo16 : SDNodeXForm<imm, [{
- return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
- MVT::i32);
-}]>;
-
-def t2_hi16 : SDNodeXForm<imm, [{
- return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
-}]>;
-
-def t2_lo16AllZero : PatLeaf<(i32 imm), [{
- // Returns true if all low 16-bits are 0.
- return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
- }], t2_hi16>;
-
-
// Define Thumb2 specific addressing modes.
// t2addrmode_imm12 := reg + imm12
@@ -681,12 +659,11 @@
"movw", " $dst, $src",
[(set GPR:$dst, imm0_65535:$src)]>;
-// FIXME: Also available in ARM mode.
let Constraints = "$src = $dst" in
def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
"movt", " $dst, $imm",
[(set GPR:$dst,
- (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
+ (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>;
//===----------------------------------------------------------------------===//
// Extend Instructions.
@@ -1153,4 +1130,4 @@
// Large immediate handling.
def : T2Pat<(i32 imm:$src),
- (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;
+ (t2MOVTi16 (t2MOVi16 (lo16 imm:$src)), (hi16 imm:$src))>;
Added: llvm/trunk/test/CodeGen/ARM/t2-imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/t2-imm.ll?rev=82948&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/t2-imm.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/t2-imm.ll Sun Sep 27 18:52:58 2009
@@ -0,0 +1,9 @@
+; RUN: llc < %s -march=arm -mattr=+thumb2 | FileCheck %s
+
+define i32 @f6(i32 %a) {
+; CHECK:f6
+; CHECK: movw r0, #1123
+; CHECK: movt r0, #1000
+ %tmp = add i32 0, 65537123
+ ret i32 %tmp
+}
More information about the llvm-commits
mailing list