ARM SelectDYN_ALLOC should emit a copy from SP rather than referencing SP directly. In cases where there are two dyn_alloc in the same BB it would have caused the old SP value to be reused and badness ensues. rdar://7493908

llvm is generating poor code for dynamic alloca, I'll fix that later.

llvm-svn: 101383
This commit is contained in:
Evan Cheng 2010-04-15 18:42:28 +00:00
parent 4230e35879
commit 1ba1428577
2 changed files with 24 additions and 1 deletions

View File

@ -945,7 +945,7 @@ SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue Size = N->getOperand(1);
SDValue Align = N->getOperand(2);
SDValue SP = CurDAG->getRegister(ARM::SP, MVT::i32);
SDValue SP = CurDAG->getCopyFromReg(Chain, dl, ARM::SP, MVT::i32);
int32_t AlignVal = cast<ConstantSDNode>(Align)->getSExtValue();
if (AlignVal < 0)
// We need to align the stack. Use Thumb1 tAND which is the only thumb

View File

@ -0,0 +1,23 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -O3 | FileCheck %s
; rdar://7493908
; Make sure the result of the first dynamic_alloc isn't copied back to sp more
; than once. We'll deal with poor codegen later.
define arm_apcscc void @t() nounwind ssp {
entry:
; CHECK: t:
; CHECK: mvn r0, #7
; CHECK: ands sp, r0
; CHECK: mov r1, sp
; CHECK: mov sp, r1
; Yes, this is stupid codegen, but it's correct.
; CHECK: sub sp, #16
; CHECK: mov r1, sp
; CHECK: mov sp, r1
; CHECK: ands sp, r0
%size = mul i32 8, 2
%vla_a = alloca i8, i32 %size, align 8
%vla_b = alloca i8, i32 %size, align 8
unreachable
}