1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

[stackprotector] Allow for copies from vreg -> vreg to be in a terminator sequence.

Sometimes a copy from a vreg -> vreg sneaks into the middle of a terminator
sequence. It is safe to slice this into the stack protector success bb.

This fixes PR16979.

llvm-svn: 191260
This commit is contained in:
Michael Gottesman 2013-09-24 01:50:26 +00:00
parent b145101bbb
commit 2ec63d27a9
2 changed files with 89 additions and 6 deletions

View File

@ -1165,13 +1165,33 @@ static bool MIIsInTerminatorSequence(const MachineInstr *MI) {
// sequence, so we return true in that case.
return MI->isDebugValue();
// If we are not defining a register that is a physical register via a copy or
// are defining a register via an implicit def, we have left the terminator
// sequence.
// We have left the terminator sequence if we are not doing one of the
// following:
//
// 1. Copying a vreg into a physical register.
// 2. Copying a vreg into a vreg.
// 3. Defining a register via an implicit def.
// OPI should always be a register definition...
MachineInstr::const_mop_iterator OPI = MI->operands_begin();
if (!OPI->isReg() || !OPI->isDef() ||
if (!OPI->isReg() || !OPI->isDef())
return false;
// Defining any register via an implicit def is always ok.
if (MI->isImplicitDef())
return true;
// Grab the copy source...
MachineInstr::const_mop_iterator OPI2 = OPI;
++OPI2;
assert(OPI2 != MI->operands_end()
&& "Should have a copy implying we should have 2 arguments.");
// Make sure that the copy dest is not a vreg when the copy source is a
// physical register.
if (!OPI2->isReg() ||
(!TargetRegisterInfo::isPhysicalRegister(OPI->getReg()) &&
!MI->isImplicitDef()))
TargetRegisterInfo::isPhysicalRegister(OPI2->getReg())))
return false;
return true;

View File

@ -0,0 +1,63 @@
; RUN: llc -mtriple i386-unknown-freebsd10.0 -march=x86 --relocation-model=pic %s -o -
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
target triple = "i386-unknown-freebsd10.0"
@state = internal unnamed_addr global i32 0, align 4
; Function Attrs: nounwind sspreq
define void @set_state(i32 %s) #0 {
entry:
store i32 %s, i32* @state, align 4, !tbaa !0
ret void
}
; Function Attrs: nounwind sspreq
define void @zero_char(i8* nocapture %p) #0 {
entry:
store i8 0, i8* %p, align 1, !tbaa !1
tail call void @g(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0) #2
ret void
}
declare void @g(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) #1
; Function Attrs: nounwind sspreq
define void @do_something(i32 %i) #0 {
entry:
%data = alloca [8 x i8], align 1
%0 = load i32* @state, align 4, !tbaa !0
%cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
tail call fastcc void @send_int(i32 0)
br label %if.end
if.else: ; preds = %entry
tail call fastcc void @send_int(i32 %i)
%arrayidx = getelementptr inbounds [8 x i8]* %data, i32 0, i32 0
call void @zero_char(i8* %arrayidx)
br label %if.end
if.end: ; preds = %if.else, %if.then
ret void
}
; Function Attrs: nounwind sspreq
define internal fastcc void @send_int(i32 %p) #0 {
entry:
tail call void @f(i32 %p) #2
tail call void @g(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0) #2
ret void
}
declare void @f(i32) #1
attributes #0 = { nounwind sspreq "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!0 = metadata !{metadata !"int", metadata !1}
!1 = metadata !{metadata !"omnipotent char", metadata !2}
!2 = metadata !{metadata !"Simple C/C++ TBAA"}