llvm.org GIT mirror llvm / a704644
Merging r276358, r276364, and r276368 ------------------------------------------------------------------------ r276358 | spop | 2016-07-21 16:22:10 -0700 (Thu, 21 Jul 2016) | 6 lines GVH-hoist: only clone GEPs (PR28606) Do not clone stored values unless they are GEPs that are special cased to avoid hoisting them without hoisting their associated ld/st. Differential revision: https://reviews.llvm.org/D22652 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r276364 | spop | 2016-07-21 16:32:39 -0700 (Thu, 21 Jul 2016) | 1 line GVN-hoist: add missing check for all GEP operands available ------------------------------------------------------------------------ ------------------------------------------------------------------------ r276368 | spop | 2016-07-21 17:07:01 -0700 (Thu, 21 Jul 2016) | 1 line GVN-hoist: move check before mutating the IR ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@276420 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 4 years ago
3 changed file(s) with 65 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
595595 if (auto *St = dyn_cast(Repl)) {
596596 Gep = dyn_cast(St->getPointerOperand());
597597 Val = dyn_cast(St->getValueOperand());
598 }
599
600 if (!Gep)
601 return false;
602
603 // PHIs may only be inserted at the start of a block.
604 if (Val && isa(Val))
605 return false;
598 // Check that the stored value is available.
599 if (Val) {
600 if (isa(Val)) {
601 // Check whether we can compute the GEP at HoistPt.
602 if (!allOperandsAvailable(Val, HoistPt))
603 return false;
604 } else if (!DT->dominates(Val->getParent(), HoistPt))
605 return false;
606 }
607 }
606608
607609 // Check whether we can compute the Gep at HoistPt.
608 if (!allOperandsAvailable(Gep, HoistPt))
609 return false;
610
611 // Also check that the stored value is available.
612 if (Val && !allOperandsAvailable(Val, HoistPt))
610 if (!Gep || !allOperandsAvailable(Gep, HoistPt))
613611 return false;
614612
615613 // Copy the gep before moving the ld/st.
617615 ClonedGep->insertBefore(HoistPt->getTerminator());
618616 replaceUseWith(Repl, Gep, ClonedGep);
619617
620 // Also copy Val.
621 if (Val) {
618 // Also copy Val when it is a GEP.
619 if (Val && isa(Val)) {
622620 Instruction *ClonedVal = Val->clone();
623621 ClonedVal->insertBefore(HoistPt->getTerminator());
624622 replaceUseWith(Repl, Val, ClonedVal);
0 ; RUN: opt -gvn-hoist -S < %s | FileCheck %s
1
2 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
3 target triple = "i686-pc-windows-msvc18.0.0"
4
5 %struct.S = type { i8* }
6
7 declare void @f(<{ %struct.S }>* inalloca)
8
9
10 ; Check that we don't clone the %x alloca and insert it in the live range of
11 ; %argmem, which would break the inalloca contract.
12 ;
13 ; CHECK-LABEL: @test
14 ; CHECK: alloca i8
15 ; CHECK: stacksave
16 ; CHECK: alloca inalloca
17 ; CHECK-NOT: alloca i8
18
19 ; Check that store instructions are hoisted.
20 ; CHECK: store i8
21 ; CHECK-NOT: store i8
22 ; CHECK: stackrestore
23
24 define void @test(i1 %b) {
25 entry:
26 %x = alloca i8
27 %inalloca.save = call i8* @llvm.stacksave()
28 %argmem = alloca inalloca <{ %struct.S }>, align 4
29 %0 = getelementptr inbounds <{ %struct.S }>, <{ %struct.S }>* %argmem, i32 0, i32 0
30 br i1 %b, label %true, label %false
31
32 true:
33 %p = getelementptr inbounds %struct.S, %struct.S* %0, i32 0, i32 0
34 store i8* %x, i8** %p, align 4
35 br label %exit
36
37 false:
38 %p2 = getelementptr inbounds %struct.S, %struct.S* %0, i32 0, i32 0
39 store i8* %x, i8** %p2, align 4
40 br label %exit
41
42 exit:
43 call void @f(<{ %struct.S }>* inalloca %argmem)
44 call void @llvm.stackrestore(i8* %inalloca.save)
45 ret void
46 }
47
48 declare i8* @llvm.stacksave()
49 declare void @llvm.stackrestore(i8*)
3737 ; CHECK: %[[gep0:.*]] = getelementptr inbounds i1, i1* %[[load]], i64 0
3838 ; CHECK: store i1 %[[phi]], i1* %[[gep0]], align 4
3939
40 ; CHECK: %[[gep1:.*]] = getelementptr inbounds i1, i1* %[[load]], i64 0
41 ; CHECK: store i1 %[[phi]], i1* %[[gep1]], align 4
40 ; Check that store instructions are hoisted.
41 ; CHECK-NOT: store