Add support for using MVN to materialize negative constants.

rdar://10412592

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144348 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chad Rosier 2011-11-11 00:36:21 +00:00
parent 7b809e08b9
commit 4e89d97e3a
3 changed files with 130 additions and 9 deletions

View File

@ -552,16 +552,30 @@ unsigned ARMFastISel::ARMMaterializeInt(const Constant *C, EVT VT) {
// do so now.
const ConstantInt *CI = cast<ConstantInt>(C);
if (Subtarget->hasV6T2Ops() && isUInt<16>(CI->getZExtValue())) {
EVT SrcVT = MVT::i32;
unsigned Opc = isThumb2 ? ARM::t2MOVi16 : ARM::MOVi16;
unsigned ImmReg = createResultReg(TLI.getRegClassFor(SrcVT));
unsigned ImmReg = createResultReg(TLI.getRegClassFor(MVT::i32));
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ImmReg)
.addImm(CI->getZExtValue()));
return ImmReg;
}
// For now 32-bit only.
// Use MVN to emit negative constants.
if (VT == MVT::i32 && Subtarget->hasV6T2Ops() && CI->isNegative()) {
unsigned Imm = (unsigned)~(CI->getSExtValue());
bool EncodeImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
(ARM_AM::getSOImmVal(Imm) != -1);
if (EncodeImm) {
unsigned Opc = isThumb2 ? ARM::t2MVNi : ARM::MVNi;
unsigned ImmReg = createResultReg(TLI.getRegClassFor(MVT::i32));
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ImmReg)
.addImm(Imm));
return ImmReg;
}
}
// Load from constant pool. For now 32-bit only.
if (VT != MVT::i32)
return false;

View File

@ -11,7 +11,7 @@ entry:
; ARM: t1
%add.ptr = getelementptr inbounds i16* %a, i64 -8
%0 = load i16* %add.ptr, align 2
; ARM: ldr r{{[1-9]}}, LCPI0_0
; ARM: mvn r{{[1-9]}}, #15
; ARM: add r0, r0, r{{[1-9]}}
; ARM: ldrh r0, [r0]
ret i16 %0
@ -23,7 +23,7 @@ entry:
; ARM: t2
%add.ptr = getelementptr inbounds i16* %a, i64 -16
%0 = load i16* %add.ptr, align 2
; ARM: ldr r{{[1-9]}}, LCPI1_0
; ARM: mvn r{{[1-9]}}, #31
; ARM: add r0, r0, r{{[1-9]}}
; ARM: ldrh r0, [r0]
ret i16 %0
@ -35,7 +35,7 @@ entry:
; ARM: t3
%add.ptr = getelementptr inbounds i16* %a, i64 -127
%0 = load i16* %add.ptr, align 2
; ARM: ldr r{{[1-9]}}, LCPI2_0
; ARM: mvn r{{[1-9]}}, #253
; ARM: add r0, r0, r{{[1-9]}}
; ARM: ldrh r0, [r0]
ret i16 %0
@ -48,7 +48,7 @@ entry:
; ARM: t4
%add.ptr = getelementptr inbounds i16* %a, i64 -128
%0 = load i16* %add.ptr, align 2
; ARM: ldr r{{[1-9]}}, LCPI3_0
; ARM: mvn r{{[1-9]}}, #255
; ARM: add r0, r0, r{{[1-9]}}
; ARM: ldrh r0, [r0]
ret i16 %0
@ -97,7 +97,7 @@ entry:
; ARM: t9
%add.ptr = getelementptr inbounds i16* %a, i64 -8
store i16 0, i16* %add.ptr, align 2
; ARM: ldr r{{[1-9]}}, LCPI8_0
; ARM: mvn r{{[1-9]}}, #15
; ARM: add r0, r0, r{{[1-9]}}
; ARM: strh r{{[1-9]}}, [r0]
ret void
@ -110,7 +110,7 @@ entry:
; ARM: t10
%add.ptr = getelementptr inbounds i16* %a, i64 -128
store i16 0, i16* %add.ptr, align 2
; ARM: ldr r{{[1-9]}}, LCPI9_0
; ARM: mvn r{{[1-9]}}, #255
; ARM: add r0, r0, r{{[1-9]}}
; ARM: strh r{{[1-9]}}, [r0]
ret void

View File

@ -0,0 +1,107 @@
; 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
; rdar://10412592
; Note: The Thumb code is being generated by the target-independent selector.
define void @t1() nounwind {
entry:
; ARM: t1
; THUMB: t1
; ARM: mvn r0, #0
; THUMB: movw r0, #65535
; THUMB: movt r0, #65535
call void @foo(i32 -1)
ret void
}
declare void @foo(i32)
define void @t2() nounwind {
entry:
; ARM: t2
; THUMB: t2
; ARM: mvn r0, #233
; THUMB: movw r0, #65302
; THUMB: movt r0, #65535
call void @foo(i32 -234)
ret void
}
define void @t3() nounwind {
entry:
; ARM: t3
; THUMB: t3
; ARM: mvn r0, #256
; THUMB: movw r0, #65279
; THUMB: movt r0, #65535
call void @foo(i32 -257)
ret void
}
; Load from constant pool
define void @t4() nounwind {
entry:
; ARM: t4
; THUMB: t4
; ARM: ldr r0
; THUMB: movw r0, #65278
; THUMB: movt r0, #65535
call void @foo(i32 -258)
ret void
}
define void @t5() nounwind {
entry:
; ARM: t5
; THUMB: t5
; ARM: mvn r0, #65280
; THUMB: movs r0, #255
; THUMB: movt r0, #65535
call void @foo(i32 -65281)
ret void
}
define void @t6() nounwind {
entry:
; ARM: t6
; THUMB: t6
; ARM: mvn r0, #978944
; THUMB: movw r0, #4095
; THUMB: movt r0, #65521
call void @foo(i32 -978945)
ret void
}
define void @t7() nounwind {
entry:
; ARM: t7
; THUMB: t7
; ARM: mvn r0, #267386880
; THUMB: movw r0, #65535
; THUMB: movt r0, #61455
call void @foo(i32 -267386881)
ret void
}
define void @t8() nounwind {
entry:
; ARM: t8
; THUMB: t8
; ARM: mvn r0, #65280
; THUMB: movs r0, #255
; THUMB: movt r0, #65535
call void @foo(i32 -65281)
ret void
}
define void @t9() nounwind {
entry:
; ARM: t9
; THUMB: t9
; ARM: mvn r0, #2130706432
; THUMB: movw r0, #65535
; THUMB: movt r0, #33023
call void @foo(i32 -2130706433)
ret void
}