diff options
author | Juergen Ributzka <juergen@apple.com> | 2014-08-28 00:09:46 +0000 |
---|---|---|
committer | Juergen Ributzka <juergen@apple.com> | 2014-08-28 00:09:46 +0000 |
commit | 4f1a54a41abf01c0b907b62568ede8bf646f8ee3 (patch) | |
tree | e83535946c1473addd6b95fef44b7d1c27acbacc /llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | |
parent | 2c38164737f70e7cb55e2935563cfb70f89ffd5f (diff) | |
download | bcm5719-llvm-4f1a54a41abf01c0b907b62568ede8bf646f8ee3.tar.gz bcm5719-llvm-4f1a54a41abf01c0b907b62568ede8bf646f8ee3.zip |
[FastISel]
Currently instructions are folded very aggressively for AArch64 into the memory
operation, which can lead to the use of killed operands:
%vreg1<def> = ADDXri %vreg0<kill>, 2
%vreg2<def> = LDRBBui %vreg0, 2
... = ... %vreg1 ...
This usually happens when the result is also used by another non-memory
instruction in the same basic block, or any instruction in another basic block.
This fix teaches hasTrivialKill to not only check the LLVM IR that the value has
a single use, but also to check if the register that represents that value has
already been used. This can happen when the instruction with the use was folded
into another instruction (in this particular case a load instruction).
This fixes rdar://problem/18142857.
llvm-svn: 216634
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/FastISel.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 0a81662e9a3..1896c67d177 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -131,7 +131,7 @@ void FastISel::flushLocalValueMap() { recomputeInsertPt(); } -bool FastISel::hasTrivialKill(const Value *V) const { +bool FastISel::hasTrivialKill(const Value *V) { // Don't consider constants or arguments to have trivial kills. const Instruction *I = dyn_cast<Instruction>(V); if (!I) @@ -143,6 +143,13 @@ bool FastISel::hasTrivialKill(const Value *V) const { !hasTrivialKill(Cast->getOperand(0))) return false; + // Even the value might have only one use in the LLVM IR, it is possible that + // FastISel might fold the use into another instruction and now there is more + // than one use at the Machine Instruction level. + unsigned Reg = lookUpRegForValue(V); + if (Reg && !MRI.use_empty(Reg)) + return false; + // GEPs with all zero indices are trivially coalesced by fast-isel. if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) if (GEP->hasAllZeroIndices() && !hasTrivialKill(GEP->getOperand(0))) |