Index: lib/Target/X86/X86SelectionDAGInfo.cpp =================================================================== --- lib/Target/X86/X86SelectionDAGInfo.cpp +++ lib/Target/X86/X86SelectionDAGInfo.cpp @@ -236,6 +236,7 @@ // If the target has enhanced REPMOVSB, then it's at least as fast to use // REP MOVSB instead of REP MOVS{W,D,Q}, and it avoids having to handle // BytesLeft. + bool Use64BitRegs = Subtarget.isTarget64BitLP64(); if (!Subtarget.hasERMSB() && !(Align & 1)) { if (Align & 2) // WORD aligned @@ -245,7 +246,7 @@ Repeats.AVT = MVT::i32; else // QWORD aligned - Repeats.AVT = Subtarget.is64Bit() ? MVT::i64 : MVT::i32; + Repeats.AVT = Use64BitRegs ? MVT::i64 : MVT::i32; if (Repeats.BytesLeft() > 0 && DAG.getMachineFunction().getFunction().optForMinSize()) { @@ -256,13 +257,13 @@ } SDValue InFlag; - Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RCX : X86::ECX, + Chain = DAG.getCopyToReg(Chain, dl, Use64BitRegs ? X86::RCX : X86::ECX, DAG.getIntPtrConstant(Repeats.Count(), dl), InFlag); InFlag = Chain.getValue(1); - Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RDI : X86::EDI, + Chain = DAG.getCopyToReg(Chain, dl, Use64BitRegs ? X86::RDI : X86::EDI, Dst, InFlag); InFlag = Chain.getValue(1); - Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RSI : X86::ESI, + Chain = DAG.getCopyToReg(Chain, dl, Use64BitRegs ? X86::RSI : X86::ESI, Src, InFlag); InFlag = Chain.getValue(1); Index: test/CodeGen/X86/pr38865.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/pr38865.ll @@ -0,0 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnux32" + +%struct.a = type { [65 x i32] } + +@c = global %struct.a zeroinitializer, align 4 + +define void @e() nounwind { +; CHECK-LABEL: e: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: subl $528, %esp # imm = 0x210 +; CHECK-NEXT: leal {{[0-9]+}}(%rsp), %ebx +; CHECK-NEXT: movl $c, %esi +; CHECK-NEXT: movl $260, %edx # imm = 0x104 +; CHECK-NEXT: movl %ebx, %edi +; CHECK-NEXT: callq memcpy +; CHECK-NEXT: movl $65, %ecx +; CHECK-NEXT: movl %esp, %edi +; CHECK-NEXT: movl %ebx, %esi +; CHECK-NEXT: rep;movsl +; CHECK-NEXT: callq d +; CHECK-NEXT: addl $528, %esp # imm = 0x210 +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: retq +entry: + %byval-temp = alloca %struct.a, align 8 + %0 = bitcast %struct.a* %byval-temp to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 8 %0, i8* align 4 bitcast (%struct.a* @c to i8*), i32 260, i1 false) + call void @d(%struct.a* byval nonnull align 8 %byval-temp) + ret void +} + +declare void @d(%struct.a* byval align 8) local_unnamed_addr #1 + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1)