mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
Fix IfConverter to handle regmask machine operands.
A regmask (typically seen on a call) clobbers the set of registers it lists. The IfConverter, in UpdatePredRedefs, was handling register defs, but not regmasks. These are slightly different to a def in that we need to add both an implicit use and def to appease the machine verifier. Otherwise, uses after the if converted call could think they are reading an undefined register. Reviewed by Matthias Braun and Quentin Colombet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236515 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
46356f6f6f
commit
92a55e80b8
@ -985,6 +985,20 @@ static void UpdatePredRedefs(MachineInstr *MI, LivePhysRegs &Redefs) {
|
|||||||
// take a mutable instruction instead of const.
|
// take a mutable instruction instead of const.
|
||||||
MachineInstr *OpMI = const_cast<MachineInstr*>(Op.getParent());
|
MachineInstr *OpMI = const_cast<MachineInstr*>(Op.getParent());
|
||||||
MachineInstrBuilder MIB(*OpMI->getParent()->getParent(), OpMI);
|
MachineInstrBuilder MIB(*OpMI->getParent()->getParent(), OpMI);
|
||||||
|
|
||||||
|
if (Op.isRegMask()) {
|
||||||
|
// First handle regmasks. They clobber any entries in the mask which
|
||||||
|
// means that we need a def for those registers.
|
||||||
|
MIB.addReg(Reg.first, RegState::Implicit | RegState::Undef);
|
||||||
|
|
||||||
|
// We also need to add an implicit def of this register for the later
|
||||||
|
// use to read from.
|
||||||
|
// For the register allocator to have allocated a register clobbered
|
||||||
|
// by the call which is used later, it must be the case that
|
||||||
|
// the call doesn't return.
|
||||||
|
MIB.addReg(Reg.first, RegState::Implicit | RegState::Define);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
assert(Op.isReg() && "Register operand required");
|
assert(Op.isReg() && "Register operand required");
|
||||||
MIB.addReg(Reg.first, RegState::Implicit | RegState::Undef);
|
MIB.addReg(Reg.first, RegState::Implicit | RegState::Undef);
|
||||||
}
|
}
|
||||||
|
45
test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
Normal file
45
test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
|
||||||
|
|
||||||
|
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
|
||||||
|
target triple = "thumbv7s-apple-ios8.0.0"
|
||||||
|
|
||||||
|
@debw = external global i8*, align 4
|
||||||
|
|
||||||
|
; This test ensures that the stack_chk call correctly puts implicit uses/defs for the regsiters
|
||||||
|
; live across it when if converting. This will be R0 which is passed to the call to free at the end
|
||||||
|
; of the function.
|
||||||
|
; Prior to this change, the stack_chk call (which does not return) would clobber R0 in its regmask,
|
||||||
|
; leading to verifier errors because the later use of R0 in free() is not live.
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test
|
||||||
|
; CHECK: stack_chk_fail
|
||||||
|
|
||||||
|
; Function Attrs: ssp
|
||||||
|
define void @test(i32 %argc, i8** nocapture readonly %argv, i32* %ptr, i32 %val) #0 {
|
||||||
|
entry:
|
||||||
|
%count.i = alloca [256 x i32], align 4
|
||||||
|
%cmp284.i = icmp eq i32 %val, 0
|
||||||
|
br i1 %cmp284.i, label %for.end31.i, label %for.body21.i
|
||||||
|
|
||||||
|
for.body21.i: ; preds = %entry
|
||||||
|
%arrayidx23.i = getelementptr inbounds [256 x i32], [256 x i32]* %count.i, i32 0, i32 1
|
||||||
|
%tmp20 = load i32, i32* %arrayidx23.i, align 4, !tbaa !0
|
||||||
|
store i32 %tmp20, i32* %ptr, align 4, !tbaa !0
|
||||||
|
br label %for.end31.i
|
||||||
|
|
||||||
|
for.end31.i: ; preds = %for.body21.i, %entry
|
||||||
|
%tmp21 = load i8*, i8** @debw, align 4, !tbaa !4
|
||||||
|
tail call void @free(i8* %tmp21)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @free(i8* nocapture)
|
||||||
|
|
||||||
|
attributes #0 = { ssp "stack-protector-buffer-size"="8" }
|
||||||
|
|
||||||
|
!0 = !{!1, !1, i64 0}
|
||||||
|
!1 = !{!"int", !2, i64 0}
|
||||||
|
!2 = !{!"omnipotent char", !3, i64 0}
|
||||||
|
!3 = !{!"Simple C/C++ TBAA"}
|
||||||
|
!4 = !{!5, !5, i64 0}
|
||||||
|
!5 = !{!"any pointer", !2, i64 0}
|
Loading…
Reference in New Issue
Block a user