File tree Expand file tree Collapse file tree 3 files changed +38
-4
lines changed
Expand file tree Collapse file tree 3 files changed +38
-4
lines changed Original file line number Diff line number Diff line change @@ -490,7 +490,10 @@ class FastISel {
490490 // / - \c Add has a constant operand.
491491 bool canFoldAddIntoGEP (const User *GEP, const Value *Add);
492492
493- // / Test whether the given value has exactly one use.
493+ // / Test whether the register associated with this value has exactly one use,
494+ // / in which case that single use is killing. Note that multiple IR values
495+ // / may map onto the same register, in which case this is not the same as
496+ // / checking that an IR value has one use.
494497 bool hasTrivialKill (const Value *V);
495498
496499 // / Create a machine mem operand from the given instruction.
Original file line number Diff line number Diff line change @@ -261,12 +261,16 @@ bool FastISel::hasTrivialKill(const Value *V) {
261261 if (GEP->hasAllZeroIndices () && !hasTrivialKill (GEP->getOperand (0 )))
262262 return false ;
263263
264+ // Casts and extractvalues may be trivially coalesced by fast-isel.
265+ if (I->getOpcode () == Instruction::BitCast ||
266+ I->getOpcode () == Instruction::PtrToInt ||
267+ I->getOpcode () == Instruction::IntToPtr ||
268+ I->getOpcode () == Instruction::ExtractValue)
269+ return false ;
270+
264271 // Only instructions with a single use in the same basic block are considered
265272 // to have trivial kills.
266273 return I->hasOneUse () &&
267- !(I->getOpcode () == Instruction::BitCast ||
268- I->getOpcode () == Instruction::PtrToInt ||
269- I->getOpcode () == Instruction::IntToPtr) &&
270274 cast<Instruction>(*I->user_begin ())->getParent () == I->getParent ();
271275}
272276
Original file line number Diff line number Diff line change 1+ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+ ; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=x86_64 < %s | FileCheck %s
3+
4+ declare { i8* , i64 } @get ()
5+
6+ declare void @use (i8* , i64 )
7+
8+ define void @test (i64* %p ) nounwind {
9+ ; CHECK-LABEL: test:
10+ ; CHECK: # %bb.0:
11+ ; CHECK-NEXT: pushq %rax
12+ ; CHECK-NEXT: movq %rdi, (%rsp) # 8-byte Spill
13+ ; CHECK-NEXT: callq get@PLT
14+ ; CHECK-NEXT: movq (%rsp), %rdi # 8-byte Reload
15+ ; CHECK-NEXT: movq %rdx, %rsi
16+ ; CHECK-NEXT: movq %rsi, (%rdi)
17+ ; CHECK-NEXT: # implicit-def: $rdi
18+ ; CHECK-NEXT: callq use@PLT
19+ ; CHECK-NEXT: popq %rax
20+ ; CHECK-NEXT: retq
21+ %struct = call { i8* , i64 } @get ()
22+ %struct.1 = extractvalue { i8* , i64 } %struct , 1
23+ store i64 %struct.1 , i64* %p , align 8
24+ %struct.2 = extractvalue { i8* , i64 } %struct , 1
25+ call void @use (i8* undef , i64 %struct.2 )
26+ ret void
27+ }
You can’t perform that action at this time.
0 commit comments