mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-14 15:39:00 +00:00
c94da20917
Summary: DataLayout keeps the string used for its creation. As a side effect it is no longer needed in the Module. This is "almost" NFC, the string is no longer canonicalized, you can't rely on two "equals" DataLayout having the same string returned by getStringRepresentation(). Get rid of DataLayoutPass: the DataLayout is in the Module The DataLayout is "per-module", let's enforce this by not duplicating it more than necessary. One more step toward non-optionality of the DataLayout in the module. Make DataLayout Non-Optional in the Module Module->getDataLayout() will never returns nullptr anymore. Reviewers: echristo Subscribers: resistor, llvm-commits, jholewinski Differential Revision: http://reviews.llvm.org/D7992 From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231270 91177308-0d34-0410-b5e6-96231b3b80d8
108 lines
3.8 KiB
LLVM
108 lines
3.8 KiB
LLVM
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
declare void @bar({i32, i32} %a)
|
|
declare i32 @baz(i32 %a)
|
|
|
|
; CHECK-LABEL: define i32 @foo(
|
|
; CHECK-NOT: extractvalue
|
|
define i32 @foo(i32 %a, i32 %b) {
|
|
; Instcombine should fold various combinations of insertvalue and extractvalue
|
|
; together
|
|
; Build a simple struct and pull values out again
|
|
%s1.1 = insertvalue {i32, i32} undef, i32 %a, 0
|
|
%s1 = insertvalue {i32, i32} %s1.1, i32 %b, 1
|
|
%v1 = extractvalue {i32, i32} %s1, 0
|
|
%v2 = extractvalue {i32, i32} %s1, 1
|
|
|
|
; Build a nested struct and pull a sub struct out of it
|
|
; This requires instcombine to insert a few insertvalue instructions
|
|
%ns1.1 = insertvalue {i32, {i32, i32}} undef, i32 %v1, 0
|
|
%ns1.2 = insertvalue {i32, {i32, i32}} %ns1.1, i32 %v1, 1, 0
|
|
%ns1 = insertvalue {i32, {i32, i32}} %ns1.2, i32 %v2, 1, 1
|
|
%s2 = extractvalue {i32, {i32, i32}} %ns1, 1
|
|
%v3 = extractvalue {i32, {i32, i32}} %ns1, 1, 1
|
|
call void @bar({i32, i32} %s2)
|
|
|
|
; Use nested extractvalues to get to a value
|
|
%s3 = extractvalue {i32, {i32, i32}} %ns1, 1
|
|
%v4 = extractvalue {i32, i32} %s3, 1
|
|
call void @bar({i32, i32} %s3)
|
|
|
|
; Use nested insertvalues to build a nested struct
|
|
%s4.1 = insertvalue {i32, i32} undef, i32 %v3, 0
|
|
%s4 = insertvalue {i32, i32} %s4.1, i32 %v4, 1
|
|
%ns2 = insertvalue {i32, {i32, i32}} undef, {i32, i32} %s4, 1
|
|
|
|
; And now extract a single value from there
|
|
%v5 = extractvalue {i32, {i32, i32}} %ns2, 1, 1
|
|
|
|
ret i32 %v5
|
|
}
|
|
|
|
; CHECK-LABEL: define i32 @extract2gep(
|
|
; CHECK-NEXT: [[GEP:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, {{.*}}* %pair, i64 0, i32 1
|
|
; CHECK-NEXT: [[LOAD:%[A-Za-z0-9]+]] = load i32, i32* [[GEP]]
|
|
; CHECK-NEXT: store
|
|
; CHECK-NEXT: br label %loop
|
|
; CHECK-NOT: extractvalue
|
|
; CHECK: call {{.*}}(i32 [[LOAD]])
|
|
; CHECK-NOT: extractvalue
|
|
; CHECK: ret i32 [[LOAD]]
|
|
define i32 @extract2gep({i32, i32}* %pair, i32* %P) {
|
|
; The load + extractvalue should be converted
|
|
; to an inbounds gep + smaller load.
|
|
; The new load should be in the same spot as the old load.
|
|
%L = load {i32, i32}, {i32, i32}* %pair
|
|
store i32 0, i32* %P
|
|
br label %loop
|
|
|
|
loop:
|
|
%E = extractvalue {i32, i32} %L, 1
|
|
%C = call i32 @baz(i32 %E)
|
|
store i32 %C, i32* %P
|
|
%cond = icmp eq i32 %C, 0
|
|
br i1 %cond, label %end, label %loop
|
|
|
|
end:
|
|
ret i32 %E
|
|
}
|
|
|
|
; CHECK-LABEL: define i32 @doubleextract2gep(
|
|
; CHECK-NEXT: [[GEP:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, {{.*}}* %arg, i64 0, i32 1, i32 1
|
|
; CHECK-NEXT: [[LOAD:%[A-Za-z0-9]+]] = load i32, i32* [[GEP]]
|
|
; CHECK-NEXT: ret i32 [[LOAD]]
|
|
define i32 @doubleextract2gep({i32, {i32, i32}}* %arg) {
|
|
; The load + extractvalues should be converted
|
|
; to a 3-index inbounds gep + smaller load.
|
|
%L = load {i32, {i32, i32}}, {i32, {i32, i32}}* %arg
|
|
%E1 = extractvalue {i32, {i32, i32}} %L, 1
|
|
%E2 = extractvalue {i32, i32} %E1, 1
|
|
ret i32 %E2
|
|
}
|
|
|
|
; CHECK: define i32 @nogep-multiuse
|
|
; CHECK-NEXT: load {{.*}} %pair
|
|
; CHECK-NEXT: extractvalue
|
|
; CHECK-NEXT: extractvalue
|
|
; CHECK-NEXT: add
|
|
; CHECK-NEXT: ret
|
|
define i32 @nogep-multiuse({i32, i32}* %pair) {
|
|
; The load should be left unchanged since both parts are needed.
|
|
%L = load volatile {i32, i32}, {i32, i32}* %pair
|
|
%LHS = extractvalue {i32, i32} %L, 0
|
|
%RHS = extractvalue {i32, i32} %L, 1
|
|
%R = add i32 %LHS, %RHS
|
|
ret i32 %R
|
|
}
|
|
|
|
; CHECK: define i32 @nogep-volatile
|
|
; CHECK-NEXT: load volatile {{.*}} %pair
|
|
; CHECK-NEXT: extractvalue
|
|
; CHECK-NEXT: ret
|
|
define i32 @nogep-volatile({i32, i32}* %pair) {
|
|
; The load volatile should be left unchanged.
|
|
%L = load volatile {i32, i32}, {i32, i32}* %pair
|
|
%E = extractvalue {i32, i32} %L, 1
|
|
ret i32 %E
|
|
}
|