1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[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.

llvm-svn: 294174
This commit is contained in:
Chandler Carruth 2017-02-06 08:43:11 +00:00
parent 29614a2ad0
commit fded0d7539
5 changed files with 117 additions and 63 deletions

View File

@ -1,25 +1,30 @@
; RUN: opt < %s -argpromotion -S > %t
; RUN: cat %t | grep "define.*@callee(.*i32\*"
; RUN: opt < %s -argpromotion -S | FileCheck %s
; PR2498
; This test tries to convince argpromotion about promoting the load from %A + 2,
; because there is a load of %A in the entry block
define internal i32 @callee(i1 %C, i32* %A) {
; CHECK-LABEL: define internal i32 @callee(
; CHECK: i1 %C, i32* %A)
entry:
; Unconditonally load the element at %A
%A.0 = load i32, i32* %A
br i1 %C, label %T, label %F
; Unconditonally load the element at %A
%A.0 = load i32, i32* %A
br i1 %C, label %T, label %F
T:
ret i32 %A.0
ret i32 %A.0
F:
; Load the element at offset two from %A. This should not be promoted!
%A.2 = getelementptr i32, i32* %A, i32 2
%R = load i32, i32* %A.2
ret i32 %R
; Load the element at offset two from %A. This should not be promoted!
%A.2 = getelementptr i32, i32* %A, i32 2
%R = load i32, i32* %A.2
ret i32 %R
}
define i32 @foo() {
; CHECK-LABEL: define i32 @foo
%X = call i32 @callee(i1 false, i32* null) ; <i32> [#uses=1]
; CHECK: call i32 @callee(i1 false, i32* null)
ret i32 %X
}

View File

@ -1,24 +1,30 @@
; RUN: opt < %s -argpromotion -instcombine -S | not grep load
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"
; RUN: opt < %s -argpromotion -S | FileCheck %s
%QuadTy = type { i32, i32, i32, i32 }
@G = constant %QuadTy {
i32 0,
i32 0,
i32 17,
i32 25 } ; <%QuadTy*> [#uses=1]
%T = type { i32, i32, i32, i32 }
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
define internal i32 @test(%QuadTy* %P) {
%A = getelementptr %QuadTy, %QuadTy* %P, i64 0, i32 3 ; <i32*> [#uses=1]
%B = getelementptr %QuadTy, %QuadTy* %P, i64 0, i32 2 ; <i32*> [#uses=1]
%a = load i32, i32* %A ; <i32> [#uses=1]
%b = load i32, i32* %B ; <i32> [#uses=1]
%V = add i32 %a, %b ; <i32> [#uses=1]
ret i32 %V
define internal i32 @test(%T* %p) {
; CHECK-LABEL: define internal i32 @test(
; CHECK: i32 %{{.*}}, i32 %{{.*}})
entry:
%a.gep = getelementptr %T, %T* %p, i64 0, i32 3
%b.gep = getelementptr %T, %T* %p, i64 0, i32 2
%a = load i32, i32* %a.gep
%b = load i32, i32* %b.gep
; CHECK-NOT: load
%v = add i32 %a, %b
ret i32 %v
; CHECK: ret i32
}
define i32 @caller() {
%V = call i32 @test( %QuadTy* @G ) ; <i32> [#uses=1]
ret i32 %V
; CHECK-LABEL: define i32 @caller(
entry:
%v = call i32 @test(%T* @G)
; CHECK: %[[B_GEP:.*]] = getelementptr %T, %T* @G, i64 0, i32 2
; CHECK: %[[B:.*]] = load i32, i32* %[[B_GEP]]
; CHECK: %[[A_GEP:.*]] = getelementptr %T, %T* @G, i64 0, i32 3
; CHECK: %[[A:.*]] = load i32, i32* %[[A_GEP]]
; CHECK: call i32 @test(i32 %[[B]], i32 %[[A]])
ret i32 %v
}

View File

@ -1,25 +1,51 @@
; RUN: opt < %s -argpromotion -S | grep zeroext
; RUN: opt < %s -argpromotion -S | FileCheck %s
%struct.ss = type { i32, i64 }
%struct.ss = type { i32, i64 }
define internal void @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
; Don't drop 'byval' on %X here.
define internal void @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
; CHECK-LABEL: define internal void @f(
; CHECK: i32 %[[B0:.*]], i64 %[[B1:.*]], i32* byval %X, i32 %i)
entry:
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
%tmp1 = load i32, i32* %tmp, align 4
%tmp2 = add i32 %tmp1, 1
store i32 %tmp2, i32* %tmp, align 4
; CHECK: %[[B:.*]] = alloca %struct.ss
; CHECK: %[[B_GEP0:.*]] = getelementptr %struct.ss, %struct.ss* %[[B]], i32 0, i32 0
; CHECK: store i32 %[[B0]], i32* %[[B_GEP0]]
; CHECK: %[[B_GEP1:.*]] = getelementptr %struct.ss, %struct.ss* %[[B]], i32 0, i32 1
; CHECK: store i64 %[[B1]], i64* %[[B_GEP1]]
store i32 0, i32* %X
ret void
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
; CHECK: %[[TMP:.*]] = getelementptr %struct.ss, %struct.ss* %[[B]], i32 0, i32 0
%tmp1 = load i32, i32* %tmp, align 4
; CHECK: %[[TMP1:.*]] = load i32, i32* %[[TMP]]
%tmp2 = add i32 %tmp1, 1
; CHECK: %[[TMP2:.*]] = add i32 %[[TMP1]], 1
store i32 %tmp2, i32* %tmp, align 4
; CHECK: store i32 %[[TMP2]], i32* %[[TMP]]
store i32 0, i32* %X
; CHECK: store i32 0, i32* %X
ret void
}
; Also make sure we don't drop the call zeroext attribute.
define i32 @test(i32* %X) {
; CHECK-LABEL: define i32 @test(
entry:
%S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
%tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1]
store i32 1, i32* %tmp1, align 8
%tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1]
store i64 2, i64* %tmp4, align 4
call void @f( %struct.ss* byval %S, i32* byval %X, i32 zeroext 0)
ret i32 0
%S = alloca %struct.ss
; CHECK: %[[S:.*]] = alloca %struct.ss
%tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
store i32 1, i32* %tmp1, align 8
; CHECK: store i32 1
%tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
store i64 2, i64* %tmp4, align 4
; CHECK: store i64 2
call void @f( %struct.ss* byval %S, i32* byval %X, i32 zeroext 0)
; CHECK: %[[S_GEP0:.*]] = getelementptr %struct.ss, %struct.ss* %[[S]], i32 0, i32 0
; CHECK: %[[S0:.*]] = load i32, i32* %[[S_GEP0]]
; CHECK: %[[S_GEP1:.*]] = getelementptr %struct.ss, %struct.ss* %[[S]], i32 0, i32 1
; CHECK: %[[S1:.*]] = load i64, i64* %[[S_GEP1]]
; CHECK: call void @f(i32 %[[S0]], i64 %[[S1]], i32* byval %X, i32 zeroext 0)
ret i32 0
}

View File

@ -1,17 +1,26 @@
; RUN: opt < %s -argpromotion -instcombine -S | not grep load
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"
; RUN: opt < %s -argpromotion -S | FileCheck %s
@G1 = constant i32 0 ; <i32*> [#uses=1]
@G2 = constant i32* @G1 ; <i32**> [#uses=1]
@G1 = constant i32 0
@G2 = constant i32* @G1
define internal i32 @test(i32** %X) {
%Y = load i32*, i32** %X ; <i32*> [#uses=1]
%X.upgrd.1 = load i32, i32* %Y ; <i32> [#uses=1]
ret i32 %X.upgrd.1
define internal i32 @test(i32** %x) {
; CHECK-LABEL: define internal i32 @test(
; CHECK: i32 %{{.*}})
entry:
%y = load i32*, i32** %x
%z = load i32, i32* %y
; CHECK-NOT: load
ret i32 %z
; CHECK: ret i32
}
define i32 @caller(i32** %P) {
%X = call i32 @test( i32** @G2 ) ; <i32> [#uses=1]
ret i32 %X
define i32 @caller() {
; CHECK-LABEL: define i32 @caller()
entry:
%x = call i32 @test(i32** @G2)
; CHECK: %[[Y:.*]] = load i32*, i32** @G2
; CHECK: %[[Z:.*]] = load i32, i32* %[[Y]]
; CHECK: call i32 @test(i32 %[[Z]])
ret i32 %x
}

View File

@ -1,19 +1,27 @@
; RUN: opt < %s -argpromotion -S | \
; RUN: not grep "load i32* null"
; Don't promote around control flow.
define internal i32 @callee(i1 %C, i32* %P) {
br i1 %C, label %T, label %F
; CHECK-LABEL: define internal i32 @callee(
; CHECK: i1 %C, i32* %P)
entry:
br i1 %C, label %T, label %F
T: ; preds = %0
ret i32 17
T:
ret i32 17
F: ; preds = %0
%X = load i32, i32* %P ; <i32> [#uses=1]
ret i32 %X
F:
%X = load i32, i32* %P
ret i32 %X
}
define i32 @foo() {
%X = call i32 @callee( i1 true, i32* null ) ; <i32> [#uses=1]
ret i32 %X
; CHECK-LABEL: define i32 @foo(
entry:
; CHECK-NOT: load i32, i32* null
%X = call i32 @callee(i1 true, i32* null)
; CHECK: call i32 @callee(i1 true, i32* null)
ret i32 %X
}