llvm.org GIT mirror llvm / f71e0b1
[ArgPromote] Replace all the grep-based testing with precise FileCheck tests. This also removes the use of instcombine as we can max the patterns produced by argument promotion directly with the more powerful tools in FileCheck. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294174 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 2 years ago
5 changed file(s) with 117 addition(s) and 63 deletion(s). Raw diff Collapse all Expand all
None ; RUN: opt < %s -argpromotion -S > %t
1 ; RUN: cat %t | grep "define.*@callee(.*i32\*"
0 ; RUN: opt < %s -argpromotion -S | FileCheck %s
21 ; PR2498
32
43 ; This test tries to convince argpromotion about promoting the load from %A + 2,
54 ; because there is a load of %A in the entry block
65 define internal i32 @callee(i1 %C, i32* %A) {
6 ; CHECK-LABEL: define internal i32 @callee(
7 ; CHECK: i1 %C, i32* %A)
78 entry:
8 ; Unconditonally load the element at %A
9 %A.0 = load i32, i32* %A
10 br i1 %C, label %T, label %F
9 ; Unconditonally load the element at %A
10 %A.0 = load i32, i32* %A
11 br i1 %C, label %T, label %F
12
1113 T:
12 ret i32 %A.0
14 ret i32 %A.0
15
1316 F:
14 ; Load the element at offset two from %A. This should not be promoted!
15 %A.2 = getelementptr i32, i32* %A, i32 2
16 %R = load i32, i32* %A.2
17 ret i32 %R
17 ; Load the element at offset two from %A. This should not be promoted!
18 %A.2 = getelementptr i32, i32* %A, i32 2
19 %R = load i32, i32* %A.2
20 ret i32 %R
1821 }
1922
2023 define i32 @foo() {
24 ; CHECK-LABEL: define i32 @foo
2125 %X = call i32 @callee(i1 false, i32* null) ; [#uses=1]
26 ; CHECK: call i32 @callee(i1 false, i32* null)
2227 ret i32 %X
2328 }
2429
None ; RUN: opt < %s -argpromotion -instcombine -S | not grep load
1 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
0 ; RUN: opt < %s -argpromotion -S | FileCheck %s
21
3 %QuadTy = type { i32, i32, i32, i32 }
4 @G = constant %QuadTy {
5 i32 0,
6 i32 0,
7 i32 17,
8 i32 25 } ; <%QuadTy*> [#uses=1]
2 %T = type { i32, i32, i32, i32 }
3 @G = constant %T { i32 0, i32 0, i32 17, i32 25 }
94
10 define internal i32 @test(%QuadTy* %P) {
11 %A = getelementptr %QuadTy, %QuadTy* %P, i64 0, i32 3 ; [#uses=1]
12 %B = getelementptr %QuadTy, %QuadTy* %P, i64 0, i32 2 ; [#uses=1]
13 %a = load i32, i32* %A ; [#uses=1]
14 %b = load i32, i32* %B ; [#uses=1]
15 %V = add i32 %a, %b ; [#uses=1]
16 ret i32 %V
5 define internal i32 @test(%T* %p) {
6 ; CHECK-LABEL: define internal i32 @test(
7 ; CHECK: i32 %{{.*}}, i32 %{{.*}})
8 entry:
9 %a.gep = getelementptr %T, %T* %p, i64 0, i32 3
10 %b.gep = getelementptr %T, %T* %p, i64 0, i32 2
11 %a = load i32, i32* %a.gep
12 %b = load i32, i32* %b.gep
13 ; CHECK-NOT: load
14 %v = add i32 %a, %b
15 ret i32 %v
16 ; CHECK: ret i32
1717 }
1818
1919 define i32 @caller() {
20 %V = call i32 @test( %QuadTy* @G ) ; [#uses=1]
21 ret i32 %V
20 ; CHECK-LABEL: define i32 @caller(
21 entry:
22 %v = call i32 @test(%T* @G)
23 ; CHECK: %[[B_GEP:.*]] = getelementptr %T, %T* @G, i64 0, i32 2
24 ; CHECK: %[[B:.*]] = load i32, i32* %[[B_GEP]]
25 ; CHECK: %[[A_GEP:.*]] = getelementptr %T, %T* @G, i64 0, i32 3
26 ; CHECK: %[[A:.*]] = load i32, i32* %[[A_GEP]]
27 ; CHECK: call i32 @test(i32 %[[B]], i32 %[[A]])
28 ret i32 %v
2229 }
23
None ; RUN: opt < %s -argpromotion -S | grep zeroext
0 ; RUN: opt < %s -argpromotion -S | FileCheck %s
11
2 %struct.ss = type { i32, i64 }
2 %struct.ss = type { i32, i64 }
33
4 define internal void @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
4 ; Don't drop 'byval' on %X here.
5 define internal void @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
6 ; CHECK-LABEL: define internal void @f(
7 ; CHECK: i32 %[[B0:.*]], i64 %[[B1:.*]], i32* byval %X, i32 %i)
58 entry:
6 %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
7 %tmp1 = load i32, i32* %tmp, align 4
8 %tmp2 = add i32 %tmp1, 1
9 store i32 %tmp2, i32* %tmp, align 4
9 ; CHECK: %[[B:.*]] = alloca %struct.ss
10 ; CHECK: %[[B_GEP0:.*]] = getelementptr %struct.ss, %struct.ss* %[[B]], i32 0, i32 0
11 ; CHECK: store i32 %[[B0]], i32* %[[B_GEP0]]
12 ; CHECK: %[[B_GEP1:.*]] = getelementptr %struct.ss, %struct.ss* %[[B]], i32 0, i32 1
13 ; CHECK: store i64 %[[B1]], i64* %[[B_GEP1]]
1014
11 store i32 0, i32* %X
12 ret void
15 %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
16 ; CHECK: %[[TMP:.*]] = getelementptr %struct.ss, %struct.ss* %[[B]], i32 0, i32 0
17 %tmp1 = load i32, i32* %tmp, align 4
18 ; CHECK: %[[TMP1:.*]] = load i32, i32* %[[TMP]]
19 %tmp2 = add i32 %tmp1, 1
20 ; CHECK: %[[TMP2:.*]] = add i32 %[[TMP1]], 1
21 store i32 %tmp2, i32* %tmp, align 4
22 ; CHECK: store i32 %[[TMP2]], i32* %[[TMP]]
23
24 store i32 0, i32* %X
25 ; CHECK: store i32 0, i32* %X
26 ret void
1327 }
1428
29 ; Also make sure we don't drop the call zeroext attribute.
1530 define i32 @test(i32* %X) {
31 ; CHECK-LABEL: define i32 @test(
1632 entry:
17 %S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
18 %tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; [#uses=1]
19 store i32 1, i32* %tmp1, align 8
20 %tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; [#uses=1]
21 store i64 2, i64* %tmp4, align 4
22 call void @f( %struct.ss* byval %S, i32* byval %X, i32 zeroext 0)
23 ret i32 0
33 %S = alloca %struct.ss
34 ; CHECK: %[[S:.*]] = alloca %struct.ss
35 %tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
36 store i32 1, i32* %tmp1, align 8
37 ; CHECK: store i32 1
38 %tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
39 store i64 2, i64* %tmp4, align 4
40 ; CHECK: store i64 2
41
42 call void @f( %struct.ss* byval %S, i32* byval %X, i32 zeroext 0)
43 ; CHECK: %[[S_GEP0:.*]] = getelementptr %struct.ss, %struct.ss* %[[S]], i32 0, i32 0
44 ; CHECK: %[[S0:.*]] = load i32, i32* %[[S_GEP0]]
45 ; CHECK: %[[S_GEP1:.*]] = getelementptr %struct.ss, %struct.ss* %[[S]], i32 0, i32 1
46 ; CHECK: %[[S1:.*]] = load i64, i64* %[[S_GEP1]]
47 ; CHECK: call void @f(i32 %[[S0]], i64 %[[S1]], i32* byval %X, i32 zeroext 0)
48
49 ret i32 0
2450 }
None ; RUN: opt < %s -argpromotion -instcombine -S | not grep load
1 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
0 ; RUN: opt < %s -argpromotion -S | FileCheck %s
21
3 @G1 = constant i32 0 ; [#uses=1]
4 @G2 = constant i32* @G1 ; [#uses=1]
2 @G1 = constant i32 0
3 @G2 = constant i32* @G1
54
6 define internal i32 @test(i32** %X) {
7 %Y = load i32*, i32** %X ; [#uses=1]
8 %X.upgrd.1 = load i32, i32* %Y ; [#uses=1]
9 ret i32 %X.upgrd.1
5 define internal i32 @test(i32** %x) {
6 ; CHECK-LABEL: define internal i32 @test(
7 ; CHECK: i32 %{{.*}})
8 entry:
9 %y = load i32*, i32** %x
10 %z = load i32, i32* %y
11 ; CHECK-NOT: load
12 ret i32 %z
13 ; CHECK: ret i32
1014 }
1115
12 define i32 @caller(i32** %P) {
13 %X = call i32 @test( i32** @G2 ) ; [#uses=1]
14 ret i32 %X
16 define i32 @caller() {
17 ; CHECK-LABEL: define i32 @caller()
18 entry:
19 %x = call i32 @test(i32** @G2)
20 ; CHECK: %[[Y:.*]] = load i32*, i32** @G2
21 ; CHECK: %[[Z:.*]] = load i32, i32* %[[Y]]
22 ; CHECK: call i32 @test(i32 %[[Z]])
23 ret i32 %x
1524 }
1625
0 ; RUN: opt < %s -argpromotion -S | \
11 ; RUN: not grep "load i32* null"
22
3 ; Don't promote around control flow.
34 define internal i32 @callee(i1 %C, i32* %P) {
4 br i1 %C, label %T, label %F
5 ; CHECK-LABEL: define internal i32 @callee(
6 ; CHECK: i1 %C, i32* %P)
7 entry:
8 br i1 %C, label %T, label %F
59
6 T: ; preds = %0
7 ret i32 17
10 T:
11 ret i32 17
812
9 F: ; preds = %0
10 %X = load i32, i32* %P ; [#uses=1]
11 ret i32 %X
13 F:
14 %X = load i32, i32* %P
15 ret i32 %X
1216 }
1317
1418 define i32 @foo() {
15 %X = call i32 @callee( i1 true, i32* null ) ; [#uses=1]
16 ret i32 %X
19 ; CHECK-LABEL: define i32 @foo(
20 entry:
21 ; CHECK-NOT: load i32, i32* null
22 %X = call i32 @callee(i1 true, i32* null)
23 ; CHECK: call i32 @callee(i1 true, i32* null)
24 ret i32 %X
1725 }
1826