/// - \c Add has a constant operand.
bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
- /// Test whether the given value has exactly one use.
+ /// Test whether the register associated with this value has exactly one use,
+ /// in which case that single use is killing. Note that multiple IR values
+ /// may map onto the same register, in which case this is not the same as
+ /// checking that an IR value has one use.
bool hasTrivialKill(const Value *V);
/// Create a machine mem operand from the given instruction.
if (GEP->hasAllZeroIndices() && !hasTrivialKill(GEP->getOperand(0)))
return false;
+ // Casts and extractvalues may be trivially coalesced by fast-isel.
+ if (I->getOpcode() == Instruction::BitCast ||
+ I->getOpcode() == Instruction::PtrToInt ||
+ I->getOpcode() == Instruction::IntToPtr ||
+ I->getOpcode() == Instruction::ExtractValue)
+ return false;
+
// Only instructions with a single use in the same basic block are considered
// to have trivial kills.
return I->hasOneUse() &&
- !(I->getOpcode() == Instruction::BitCast ||
- I->getOpcode() == Instruction::PtrToInt ||
- I->getOpcode() == Instruction::IntToPtr) &&
cast<Instruction>(*I->user_begin())->getParent() == I->getParent();
}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=x86_64 < %s | FileCheck %s
+
+declare { i8*, i64 } @get()
+
+declare void @use(i8*, i64)
+
+define void @test(i64* %p) nounwind {
+; CHECK-LABEL: test:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: movq %rdi, (%rsp) # 8-byte Spill
+; CHECK-NEXT: callq get@PLT
+; CHECK-NEXT: movq (%rsp), %rdi # 8-byte Reload
+; CHECK-NEXT: movq %rdx, %rsi
+; CHECK-NEXT: movq %rsi, (%rdi)
+; CHECK-NEXT: # implicit-def: $rdi
+; CHECK-NEXT: callq use@PLT
+; CHECK-NEXT: popq %rax
+; CHECK-NEXT: retq
+ %struct = call { i8*, i64 } @get()
+ %struct.1 = extractvalue { i8*, i64 } %struct, 1
+ store i64 %struct.1, i64* %p, align 8
+ %struct.2 = extractvalue { i8*, i64 } %struct, 1
+ call void @use(i8* undef, i64 %struct.2)
+ ret void
+}