forked from OSchip/llvm-project
Add support for using immediates with select instructions.
rdar://10412592 llvm-svn: 144376
This commit is contained in:
parent
6049446c47
commit
7ddd63ce4e
|
@ -1491,17 +1491,49 @@ bool ARMFastISel::SelectSelect(const Instruction *I) {
|
|||
if (CondReg == 0) return false;
|
||||
unsigned Op1Reg = getRegForValue(I->getOperand(1));
|
||||
if (Op1Reg == 0) return false;
|
||||
unsigned Op2Reg = getRegForValue(I->getOperand(2));
|
||||
if (Op2Reg == 0) return false;
|
||||
|
||||
unsigned CmpOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
|
||||
// Check to see if we can use an immediate in the conditional move.
|
||||
int Imm = 0;
|
||||
bool UseImm = false;
|
||||
bool isNegativeImm = false;
|
||||
if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(I->getOperand(2))) {
|
||||
assert (VT == MVT::i32 && "Expecting an i32.");
|
||||
Imm = (int)ConstInt->getValue().getZExtValue();
|
||||
if (Imm < 0) {
|
||||
isNegativeImm = true;
|
||||
Imm = ~Imm;
|
||||
}
|
||||
UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
|
||||
(ARM_AM::getSOImmVal(Imm) != -1);
|
||||
}
|
||||
|
||||
unsigned Op2Reg;
|
||||
if (!UseImm) {
|
||||
Op2Reg = getRegForValue(I->getOperand(2));
|
||||
if (Op2Reg == 0) return false;
|
||||
}
|
||||
|
||||
unsigned CmpOpc = isThumb2 ? ARM::t2CMPri : ARM::CMPri;
|
||||
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
|
||||
.addReg(CondReg).addImm(1));
|
||||
.addReg(CondReg).addImm(0));
|
||||
|
||||
unsigned MovCCOpc;
|
||||
if (!UseImm) {
|
||||
MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr;
|
||||
} else {
|
||||
if (!isNegativeImm) {
|
||||
MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
|
||||
} else {
|
||||
MovCCOpc = isThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi;
|
||||
}
|
||||
}
|
||||
unsigned ResultReg = createResultReg(RC);
|
||||
unsigned MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr;
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
|
||||
.addReg(Op1Reg).addReg(Op2Reg)
|
||||
.addImm(ARMCC::EQ).addReg(ARM::CPSR);
|
||||
if (!UseImm)
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
|
||||
.addReg(Op2Reg).addReg(Op1Reg).addImm(ARMCC::NE).addReg(ARM::CPSR);
|
||||
else
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
|
||||
.addReg(Op1Reg).addImm(Imm).addImm(ARMCC::EQ).addReg(ARM::CPSR);
|
||||
UpdateValueMap(I, ResultReg);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=ARM
|
||||
; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=THUMB
|
||||
|
||||
define i32 @t1(i1 %c) nounwind readnone {
|
||||
entry:
|
||||
; ARM: t1
|
||||
; ARM: movw r{{[1-9]}}, #10
|
||||
; ARM: cmp r0, #0
|
||||
; ARM: moveq r{{[1-9]}}, #20
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t1
|
||||
; THUMB: movs r{{[1-9]}}, #10
|
||||
; THUMB: movt r{{[1-9]}}, #0
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: moveq r{{[1-9]}}, #20
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 10, i32 20
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @t2(i1 %c, i32 %a) nounwind readnone {
|
||||
entry:
|
||||
; ARM: t2
|
||||
; ARM: cmp r0, #0
|
||||
; ARM: moveq r{{[1-9]}}, #20
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t2
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: moveq r{{[1-9]}}, #20
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 %a, i32 20
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @t3(i1 %c, i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
; ARM: t3
|
||||
; ARM: cmp r0, #0
|
||||
; ARM: movne r{{[1-9]}}, r{{[1-9]}}
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t3
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it ne
|
||||
; THUMB: movne r{{[1-9]}}, r{{[1-9]}}
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 %a, i32 %b
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @t4(i1 %c) nounwind readnone {
|
||||
entry:
|
||||
; ARM: t4
|
||||
; ARM: mvn r{{[1-9]}}, #9
|
||||
; ARM: cmp r0, #0
|
||||
; ARM: mvneq r{{[1-9]}}, #0
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t4
|
||||
; THUMB: movw r{{[1-9]}}, #65526
|
||||
; THUMB: movt r{{[1-9]}}, #65535
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: mvneq r{{[1-9]}}, #0
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 -10, i32 -1
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @t5(i1 %c, i32 %a) nounwind readnone {
|
||||
entry:
|
||||
; ARM: t5
|
||||
; ARM: cmp r0, #0
|
||||
; ARM: mvneq r{{[1-9]}}, #1
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t5
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: mvneq r{{[1-9]}}, #1
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 %a, i32 -2
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
; Check one large negative immediates.
|
||||
define i32 @t6(i1 %c, i32 %a) nounwind readnone {
|
||||
entry:
|
||||
; ARM: t6
|
||||
; ARM: cmp r0, #0
|
||||
; ARM: mvneq r{{[1-9]}}, #978944
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t6
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: mvneq r{{[1-9]}}, #978944
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 %a, i32 -978945
|
||||
ret i32 %0
|
||||
}
|
Loading…
Reference in New Issue