summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/FastISel.h2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp9
-rw-r--r--llvm/test/CodeGen/AArch64/fast-isel-addressing-modes.ll10
3 files changed, 19 insertions, 2 deletions
diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h
index b0503f0391f..ed370c3e67c 100644
--- a/llvm/include/llvm/CodeGen/FastISel.h
+++ b/llvm/include/llvm/CodeGen/FastISel.h
@@ -525,7 +525,7 @@ protected:
bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
/// Test whether the given value has exactly one use.
- bool hasTrivialKill(const Value *V) const;
+ bool hasTrivialKill(const Value *V);
/// \brief Create a machine mem operand from the given instruction.
MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
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)))
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-addressing-modes.ll b/llvm/test/CodeGen/AArch64/fast-isel-addressing-modes.ll
index 750e081d423..86755d90c63 100644
--- a/llvm/test/CodeGen/AArch64/fast-isel-addressing-modes.ll
+++ b/llvm/test/CodeGen/AArch64/fast-isel-addressing-modes.ll
@@ -478,3 +478,13 @@ define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {
ret i64 %6
}
+; Test that the kill flag is not set - the machine instruction verifier does that for us.
+define i64 @kill_reg(i64 %a) {
+ %1 = sub i64 %a, 8
+ %2 = add i64 %1, 96
+ %3 = inttoptr i64 %2 to i64*
+ %4 = load i64* %3
+ %5 = add i64 %2, %4
+ ret i64 %5
+}
+
OpenPOWER on IntegriCloud