From: Michael Kuperstein Date: Thu, 6 Oct 2016 19:31:27 +0000 (+0000) Subject: [X86] Preserve BasePtr for LEA64_32r X-Git-Tag: llvmorg-4.0.0-rc1~7885 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e524e228463c337aff8bd9b0b9099aa4fc23f31d;p=platform%2Fupstream%2Fllvm.git [X86] Preserve BasePtr for LEA64_32r When replacing FrameIndex with BasePtr, we must preserve BasePtr for LEA64_32r since BasePtr is used later for stack adjustment if it is the same as StackPtr. Patch by H.J Lu Differential Revision: https://reviews.llvm.org/D23575 llvm-svn: 283486 --- diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 5a33b5d..4401d17 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -669,12 +669,14 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // For LEA64_32r when BasePtr is 32-bits (X32) we can use full-size 64-bit // register as source operand, semantic is the same and destination is // 32-bits. It saves one byte per lea in code since 0x67 prefix is avoided. + // Don't change BasePtr since it is used later for stack adjustment. + unsigned MachineBasePtr = BasePtr; if (Opc == X86::LEA64_32r && X86::GR32RegClass.contains(BasePtr)) - BasePtr = getX86SubSuperRegister(BasePtr, 64); + MachineBasePtr = getX86SubSuperRegister(BasePtr, 64); // This must be part of a four operand memory reference. Replace the - // FrameIndex with base register with EBP. Add an offset to the offset. - MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); + // FrameIndex with base register. Add an offset to the offset. + MI.getOperand(FIOperandNum).ChangeToRegister(MachineBasePtr, false); // Now add the frame object offset to the offset from EBP. int FIOffset; diff --git a/llvm/test/CodeGen/X86/x32-movtopush64.ll b/llvm/test/CodeGen/X86/x32-movtopush64.ll new file mode 100644 index 0000000..d31628d --- /dev/null +++ b/llvm/test/CodeGen/X86/x32-movtopush64.ll @@ -0,0 +1,44 @@ +; RUN: llc < %s -mtriple=x86_64-linux-gnux32 | FileCheck %s -check-prefix=CHECK + +declare void @bar(i32*, i32*, i32*, i32*, i32*, i64*, i32, i32, i32) + +; Function Attrs: nounwind uwtable +define void @foo() { +entry: + %i1 = alloca i32, align 4 + %i2 = alloca i32, align 4 + %i3 = alloca i32, align 4 + %i4 = alloca i32, align 4 + %i5 = alloca i32, align 4 + %i6 = alloca i64, align 8 + %0 = bitcast i32* %i1 to i8* + store i32 1, i32* %i1, align 4 +; CHECK: movl $1, 28(%esp) + %1 = bitcast i32* %i2 to i8* + store i32 2, i32* %i2, align 4 +; CHECK-NEXT: movl $2, 24(%esp) + %2 = bitcast i32* %i3 to i8* + store i32 3, i32* %i3, align 4 +; CHECK-NEXT: movl $3, 20(%esp) + %3 = bitcast i32* %i4 to i8* + store i32 4, i32* %i4, align 4 +; CHECK-NEXT: movl $4, 16(%esp) + %4 = bitcast i32* %i5 to i8* + store i32 5, i32* %i5, align 4 +; CHECK-NEXT: movl $5, 12(%esp) + %5 = bitcast i64* %i6 to i8* + store i64 6, i64* %i6, align 8 +; CHECK-NEXT: movq $6, 32(%esp) +; CHECK-NEXT: subl $8, %esp +; CHECK: leal 36(%rsp), %edi +; CHECK-NEXT: leal 32(%rsp), %esi +; CHECK-NEXT: leal 28(%rsp), %edx +; CHECK-NEXT: leal 24(%rsp), %ecx +; CHECK-NEXT: leal 20(%rsp), %r8d +; CHECK-NEXT: leal 40(%rsp), %r9d +; CHECK: pushq $0 +; CHECK: pushq $0 +; CHECK: pushq $0 + call void @bar(i32* nonnull %i1, i32* nonnull %i2, i32* nonnull %i3, i32* nonnull %i4, i32* nonnull %i5, i64* nonnull %i6, i32 0, i32 0, i32 0) + ret void +}