Do not assume the value passed to memset is an i32.

The code in SelectionDAG::getMemset for some reason assumes the value passed to
memset is an i32. This breaks the generated code for targets that only have
registers smaller than 32 bits because the value might get split into multiple
registers by the calling convention. See the test for the MSP430 target included
in the patch for an example.

This patch ensures that nothing is assumed about the type of the value. Instead,
the type is taken from the selected overload of the llvm.memset intrinsic.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216716 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Job Noorman 2014-08-29 08:23:53 +00:00
parent 95f7e2d2fd
commit d2323fc295
2 changed files with 23 additions and 8 deletions

View File

@ -4361,18 +4361,11 @@ SDValue SelectionDAG::getMemset(SDValue Chain, SDLoc dl, SDValue Dst,
TargetLowering::ArgListEntry Entry;
Entry.Node = Dst; Entry.Ty = IntPtrTy;
Args.push_back(Entry);
// Extend or truncate the argument to be an i32 value for the call.
if (Src.getValueType().bitsGT(MVT::i32))
Src = getNode(ISD::TRUNCATE, dl, MVT::i32, Src);
else
Src = getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src);
Entry.Node = Src;
Entry.Ty = Type::getInt32Ty(*getContext());
Entry.isSExt = true;
Entry.Ty = Src.getValueType().getTypeForEVT(*getContext());
Args.push_back(Entry);
Entry.Node = Size;
Entry.Ty = IntPtrTy;
Entry.isSExt = false;
Args.push_back(Entry);
// FIXME: pass in SDLoc

View File

@ -0,0 +1,22 @@
; RUN: llc < %s | FileCheck %s
target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"
target triple = "msp430---elf"
@buf = external global i8*
; Function Attrs: nounwind
define void @test() nounwind {
entry:
; CHECK-LABEL: test:
%0 = load i8** @buf, align 2
; CHECK: mov.w &buf, r15
; CHECK-NEXT: mov.w #5, r14
; CHECK-NEXT: mov.w #128, r13
; CHECK-NEXT: call #memset
call void @llvm.memset.p0i8.i16(i8* %0, i8 5, i16 128, i32 1, i1 false)
ret void
}
; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i16(i8* nocapture, i8, i16, i32, i1) nounwind