diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-10-21 08:15:52 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-10-21 08:15:52 +0000 |
commit | 89ef28530fcc03f47245644eb67085b94efd0bac (patch) | |
tree | 8788a1c1389492e0a8c74e227d0e48e53e7ff685 | |
parent | 8c56cfc79c02c68bef1c8bc37f8ee7a47c5e2e32 (diff) | |
download | external_llvm-89ef28530fcc03f47245644eb67085b94efd0bac.zip external_llvm-89ef28530fcc03f47245644eb67085b94efd0bac.tar.gz external_llvm-89ef28530fcc03f47245644eb67085b94efd0bac.tar.bz2 |
Match more patterns to movt.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84751 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 37 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 3 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 2 | ||||
-rw-r--r-- | test/CodeGen/ARM/movt.ll | 19 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/thumb2-mov2.ll | 20 |
6 files changed, 65 insertions, 17 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index c39de0a..6e97693 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1427,6 +1427,43 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { } } break; + case ISD::AND: { + // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits + // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits + // are entirely contributed by c2 and lower 16-bits are entirely contributed + // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). + // Select it to: "movt x, ((c1 & 0xffff) >> 16) + EVT VT = Op.getValueType(); + if (VT != MVT::i32) + break; + unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) + ? ARM::t2MOVTi16 + : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); + if (!Opc) + break; + SDValue N0 = Op.getOperand(0), N1 = Op.getOperand(1); + ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); + if (!N1C) + break; + if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) { + SDValue N2 = N0.getOperand(1); + ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); + if (!N2C) + break; + unsigned N1CVal = N1C->getZExtValue(); + unsigned N2CVal = N2C->getZExtValue(); + if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) && + (N1CVal & 0xffffU) == 0xffffU && + (N2CVal & 0xffffU) == 0x0U) { + SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16, + MVT::i32); + SDValue Ops[] = { N0.getOperand(0), Imm16, + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->getMachineNode(Opc, dl, VT, Ops, 4); + } + } + break; + } case ARMISD::FMRRD: return CurDAG->getMachineNode(ARM::FMRRD, dl, MVT::i32, MVT::i32, Op.getOperand(0), getAL(CurDAG), diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 1752880..8693a8a 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -3022,7 +3022,6 @@ static SDValue PerformSUBCombine(SDNode *N, return SDValue(); } - /// PerformFMRRDCombine - Target-specific dag combine xforms for ARMISD::FMRRD. static SDValue PerformFMRRDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) { diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 3e0691c..e6a0bfa 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -980,6 +980,9 @@ def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm), let Inst{25} = 1; } +def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, + Requires<[IsARM, HasV6T2]>; + let Uses = [CPSR] in def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi, "mov", " $dst, $src, rrx", diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 0750dcc..b151c99 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -666,6 +666,8 @@ def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi, [(set GPR:$dst, (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>; +def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>; + //===----------------------------------------------------------------------===// // Extend Instructions. // diff --git a/test/CodeGen/ARM/movt.ll b/test/CodeGen/ARM/movt.ll new file mode 100644 index 0000000..e82aca0 --- /dev/null +++ b/test/CodeGen/ARM/movt.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -march=arm -mattr=+thumb2 | FileCheck %s +; rdar://7317664 + +define i32 @t(i32 %X) nounwind { +; CHECK: t: +; CHECK: movt r0, #65535 +entry: + %0 = or i32 %X, -65536 + ret i32 %0 +} + +define i32 @t2(i32 %X) nounwind { +; CHECK: t2: +; CHECK: movt r0, #65534 +entry: + %0 = or i32 %X, -131072 + %1 = and i32 %0, -65537 + ret i32 %1 +} diff --git a/test/CodeGen/Thumb2/thumb2-mov2.ll b/test/CodeGen/Thumb2/thumb2-mov2.ll index a02f4f0..32d0075 100644 --- a/test/CodeGen/Thumb2/thumb2-mov2.ll +++ b/test/CodeGen/Thumb2/thumb2-mov2.ll @@ -2,10 +2,7 @@ define i32 @t2MOVTi16_ok_1(i32 %a) { ; CHECK: t2MOVTi16_ok_1: -; CHECK: movs r1, #0 -; CHECK-NEXT: movt r1, #1234 -; CHECK: movw r1, #65535 -; CHECK-NEXT: movt r1, #1234 +; CHECK: movt r0, #1234 %1 = and i32 %a, 65535 %2 = shl i32 1234, 16 %3 = or i32 %1, %2 @@ -15,10 +12,7 @@ define i32 @t2MOVTi16_ok_1(i32 %a) { define i32 @t2MOVTi16_test_1(i32 %a) { ; CHECK: t2MOVTi16_test_1: -; CHECK: movs r1, #0 -; CHECK-NEXT: movt r1, #1234 -; CHECK: movw r1, #65535 -; CHECK-NEXT: movt r1, #1234 +; CHECK: movt r0, #1234 %1 = shl i32 255, 8 %2 = shl i32 1234, 8 %3 = or i32 %1, 255 ; This give us 0xFFFF in %3 @@ -31,10 +25,7 @@ define i32 @t2MOVTi16_test_1(i32 %a) { define i32 @t2MOVTi16_test_2(i32 %a) { ; CHECK: t2MOVTi16_test_2: -; CHECK: movs r1, #0 -; CHECK-NEXT: movt r1, #1234 -; CHECK: movw r1, #65535 -; CHECK-NEXT: movt r1, #1234 +; CHECK: movt r0, #1234 %1 = shl i32 255, 8 %2 = shl i32 1234, 8 %3 = or i32 %1, 255 ; This give us 0xFFFF in %3 @@ -48,10 +39,7 @@ define i32 @t2MOVTi16_test_2(i32 %a) { define i32 @t2MOVTi16_test_3(i32 %a) { ; CHECK: t2MOVTi16_test_3: -; CHECK: movs r1, #0 -; CHECK-NEXT: movt r1, #1234 -; CHECK: movw r1, #65535 -; CHECK-NEXT: movt r1, #1234 +; CHECK: movt r0, #1234 %1 = shl i32 255, 8 %2 = shl i32 1234, 8 %3 = or i32 %1, 255 ; This give us 0xFFFF in %3 |