diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h index b0503f0391fe..ed370c3e67cb 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 0a81662e9a3e..1896c67d1776 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(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(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 750e081d4236..86755d90c632 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 +} +