WebAssembly: don't optimize memcpy/memmove/memcpy to frame index

r258781 optimized memcpy/memmove/memcpy so the intrinsic call can return its first argument, but missed the frame index case. Teach it to ignore that case so C code doesn't assert out in these cases.

llvm-svn: 258851
This commit is contained in:
JF Bastien 2016-01-26 20:22:42 +00:00
parent bacf7e4f39
commit 1a6c7608b1
3 changed files with 42 additions and 20 deletions

View File

@ -113,16 +113,21 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
Name == TLI.getLibcallName(RTLIB::MEMSET)) { Name == TLI.getLibcallName(RTLIB::MEMSET)) {
LibFunc::Func Func; LibFunc::Func Func;
if (LibInfo.getLibFunc(Name, Func)) { if (LibInfo.getLibFunc(Name, Func)) {
if (!MI.getOperand(2).isReg()) const auto &Op2 = MI.getOperand(2);
report_fatal_error( if (Op2.isReg()) {
"Call to builtin function with wrong signature"); MachineOperand &MO = MI.getOperand(0);
MachineOperand &MO = MI.getOperand(0); unsigned OldReg = MO.getReg();
unsigned OldReg = MO.getReg(); unsigned NewReg = Op2.getReg();
unsigned NewReg = MI.getOperand(2).getReg(); if (MRI.getRegClass(NewReg) != MRI.getRegClass(OldReg))
if (MRI.getRegClass(NewReg) != MRI.getRegClass(OldReg)) report_fatal_error("Peephole: call to builtin function with "
report_fatal_error( "wrong signature, from/to mismatch");
"Call to builtin function with wrong signature"); Changed |= MaybeRewriteToDiscard(OldReg, NewReg, MO, MFI, MRI);
Changed |= MaybeRewriteToDiscard(OldReg, NewReg, MO, MFI, MRI); } else if (Op2.isFI()) {
break;
} else {
report_fatal_error("Peephole: call to builtin function with "
"wrong signature, not consuming reg");
}
} }
} }
} }

View File

@ -150,16 +150,22 @@ bool WebAssemblyStoreResults::runOnMachineFunction(MachineFunction &MF) {
Name == TLI.getLibcallName(RTLIB::MEMSET)) { Name == TLI.getLibcallName(RTLIB::MEMSET)) {
LibFunc::Func Func; LibFunc::Func Func;
if (LibInfo.getLibFunc(Name, Func)) { if (LibInfo.getLibFunc(Name, Func)) {
if (!MI.getOperand(2).isReg()) const auto &Op2 = MI.getOperand(2);
report_fatal_error( if (Op2.isReg()) {
"Call to builtin function with wrong signature"); unsigned FromReg = Op2.getReg();
unsigned FromReg = MI.getOperand(2).getReg(); unsigned ToReg = MI.getOperand(0).getReg();
unsigned ToReg = MI.getOperand(0).getReg(); if (MRI.getRegClass(FromReg) != MRI.getRegClass(ToReg))
if (MRI.getRegClass(FromReg) != MRI.getRegClass(ToReg)) report_fatal_error("Store results: call to builtin function "
report_fatal_error( "with wrong signature, from/to mismatch");
"Call to builtin function with wrong signature"); Changed |=
Changed |= ReplaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT);
ReplaceDominatedUses(MBB, MI, FromReg, ToReg, MRI, MDT); } else if (Op2.isFI()) {
break;
} else {
report_fatal_error("Store results: call to builtin function "
"with wrong signature, not consuming reg or "
"frame index");
}
} }
} }
} }

View File

@ -58,3 +58,14 @@ define void @set_no(i8* %dst, i8 %src, i32 %len) {
call void @llvm.memset.p0i8.i32(i8* %dst, i8 %src, i32 %len, i32 1, i1 false) call void @llvm.memset.p0i8.i32(i8* %dst, i8 %src, i32 %len, i32 1, i1 false)
ret void ret void
} }
; CHECK-LABEL: frame_index:
; CHECK: i32.call $discard=, memset@FUNCTION, $3, $pop1, $pop0{{$}}
; CHECK: return{{$}}
define void @frame_index() {
entry:
%a = alloca [2048 x i8], align 16
%0 = getelementptr inbounds [2048 x i8], [2048 x i8]* %a, i32 0, i32 0
call void @llvm.memset.p0i8.i32(i8* %0, i8 256, i32 1024, i32 16, i1 false)
ret void
}