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 {
490
490
// / - \c Add has a constant operand.
491
491
bool canFoldAddIntoGEP (const User *GEP, const Value *Add);
492
492
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.
494
497
bool hasTrivialKill (const Value *V);
495
498
496
499
// / 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) {
261
261
if (GEP->hasAllZeroIndices () && !hasTrivialKill (GEP->getOperand (0 )))
262
262
return false ;
263
263
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
+
264
271
// Only instructions with a single use in the same basic block are considered
265
272
// to have trivial kills.
266
273
return I->hasOneUse () &&
267
- !(I->getOpcode () == Instruction::BitCast ||
268
- I->getOpcode () == Instruction::PtrToInt ||
269
- I->getOpcode () == Instruction::IntToPtr) &&
270
274
cast<Instruction>(*I->user_begin ())->getParent () == I->getParent ();
271
275
}
272
276
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