[XCore] Don't create invalid MKMSK instructions inside loadImmediate().

Summary:
Previously loadImmediate() would produce MKMSK instructions with invalid
immediate values such as mkmsk r0, 9. Fix this by checking the mask size
is valid.

Reviewers: robertlytton

Reviewed By: robertlytton

CC: llvm-commits

Differential Revision: http://reviews.llvm.org/D3289

llvm-svn: 206163
This commit is contained in:
Richard Osborne 2014-04-14 12:30:35 +00:00
parent 1a21e608ca
commit 6d5512a94e
2 changed files with 41 additions and 6 deletions

View File

@ -428,13 +428,21 @@ static inline bool isImmU16(unsigned val) {
return val < (1 << 16); return val < (1 << 16);
} }
static bool isImmMskBitp(unsigned val) {
if (!isMask_32(val)) {
return false;
}
int N = Log2_32(val) + 1;
return (N >= 1 && N <= 8) || N == 16 || N == 24 || N == 32;
}
MachineBasicBlock::iterator XCoreInstrInfo::loadImmediate( MachineBasicBlock::iterator XCoreInstrInfo::loadImmediate(
MachineBasicBlock &MBB, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, MachineBasicBlock::iterator MI,
unsigned Reg, uint64_t Value) const { unsigned Reg, uint64_t Value) const {
DebugLoc dl; DebugLoc dl;
if (MI != MBB.end()) dl = MI->getDebugLoc(); if (MI != MBB.end()) dl = MI->getDebugLoc();
if (isMask_32(Value)) { if (isImmMskBitp(Value)) {
int N = Log2_32(Value) + 1; int N = Log2_32(Value) + 1;
return BuildMI(MBB, MI, dl, get(XCore::MKMSK_rus), Reg).addImm(N); return BuildMI(MBB, MI, dl, get(XCore::MKMSK_rus), Reg).addImm(N);
} }

View File

@ -206,14 +206,41 @@ entry:
ret i32 %i ret i32 %i
} }
; FP + large frame: spill FP+SR+LR = entsp 2 + 256 + extsp 1
; CHECKFP-LABEL:f8
; CHECKFP: entsp 258
; CHECKFP-NEXT: stw r10, sp[1]
; CHECKFP-NEXT: ldaw r10, sp[0]
; CHECKFP-NEXT: mkmsk [[REG:r[0-9]+]], 8
; CHECKFP-NEXT: ldaw r0, r10{{\[}}[[REG]]{{\]}}
; CHECKFP-NEXT: extsp 1
; CHECKFP-NEXT: bl f5
; CHECKFP-NEXT: ldaw sp, sp[1]
; CHECKFP-NEXT: set sp, r10
; CHECKFP-NEXT: ldw r10, sp[1]
; CHECKFP-NEXT: retsp 258
;
; !FP + large frame: spill SR+SR+LR = entsp 3 + 256
; CHECK-LABEL:f8
; CHECK: entsp 257
; CHECK-NEXT: ldaw r0, sp[254]
; CHECK-NEXT: bl f5
; CHECK-NEXT: retsp 257
define void @f8() nounwind {
entry:
%0 = alloca [256 x i32]
%1 = getelementptr inbounds [256 x i32]* %0, i32 0, i32 253
call void @f5(i32* %1)
ret void
}
; FP + large frame: spill FP+SR+LR = entsp 2 + 32768 + extsp 1 ; FP + large frame: spill FP+SR+LR = entsp 2 + 32768 + extsp 1
; CHECKFP-LABEL:f8 ; CHECKFP-LABEL:f9
; CHECKFP: entsp 32770 ; CHECKFP: entsp 32770
; CHECKFP-NEXT: stw r10, sp[1] ; CHECKFP-NEXT: stw r10, sp[1]
; CHECKFP-NEXT: ldaw r10, sp[0] ; CHECKFP-NEXT: ldaw r10, sp[0]
; CHECKFP-NEXT: mkmsk r1, 15 ; CHECKFP-NEXT: ldc [[REG:r[0-9]+]], 32767
; CHECKFP-NEXT: ldaw r0, r10[r1] ; CHECKFP-NEXT: ldaw r0, r10{{\[}}[[REG]]{{\]}}
; CHECKFP-NEXT: extsp 1 ; CHECKFP-NEXT: extsp 1
; CHECKFP-NEXT: bl f5 ; CHECKFP-NEXT: bl f5
; CHECKFP-NEXT: ldaw sp, sp[1] ; CHECKFP-NEXT: ldaw sp, sp[1]
@ -222,12 +249,12 @@ entry:
; CHECKFP-NEXT: retsp 32770 ; CHECKFP-NEXT: retsp 32770
; ;
; !FP + large frame: spill SR+SR+LR = entsp 3 + 32768 ; !FP + large frame: spill SR+SR+LR = entsp 3 + 32768
; CHECK-LABEL:f8 ; CHECK-LABEL:f9
; CHECK: entsp 32771 ; CHECK: entsp 32771
; CHECK-NEXT: ldaw r0, sp[32768] ; CHECK-NEXT: ldaw r0, sp[32768]
; CHECK-NEXT: bl f5 ; CHECK-NEXT: bl f5
; CHECK-NEXT: retsp 32771 ; CHECK-NEXT: retsp 32771
define void @f8() nounwind { define void @f9() nounwind {
entry: entry:
%0 = alloca [32768 x i32] %0 = alloca [32768 x i32]
%1 = getelementptr inbounds [32768 x i32]* %0, i32 0, i32 32765 %1 = getelementptr inbounds [32768 x i32]* %0, i32 0, i32 32765