xref: /aosp_15_r20/external/llvm/test/Transforms/InstCombine/extractvalue.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdeclare void @bar({i32, i32} %a)
4*9880d681SAndroid Build Coastguard Workerdeclare i32 @baz(i32 %a)
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @foo(
7*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: extractvalue
8*9880d681SAndroid Build Coastguard Workerdefine i32 @foo(i32 %a, i32 %b) {
9*9880d681SAndroid Build Coastguard Worker; Instcombine should fold various combinations of insertvalue and extractvalue
10*9880d681SAndroid Build Coastguard Worker; together
11*9880d681SAndroid Build Coastguard Worker        ; Build a simple struct and pull values out again
12*9880d681SAndroid Build Coastguard Worker        %s1.1 = insertvalue {i32, i32} undef, i32 %a, 0
13*9880d681SAndroid Build Coastguard Worker        %s1 = insertvalue {i32, i32} %s1.1, i32 %b, 1
14*9880d681SAndroid Build Coastguard Worker        %v1 = extractvalue {i32, i32} %s1, 0
15*9880d681SAndroid Build Coastguard Worker        %v2 = extractvalue {i32, i32} %s1, 1
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker        ; Build a nested struct and pull a sub struct out of it
18*9880d681SAndroid Build Coastguard Worker        ; This requires instcombine to insert a few insertvalue instructions
19*9880d681SAndroid Build Coastguard Worker        %ns1.1 = insertvalue {i32, {i32, i32}} undef, i32 %v1, 0
20*9880d681SAndroid Build Coastguard Worker        %ns1.2 = insertvalue {i32, {i32, i32}} %ns1.1, i32 %v1, 1, 0
21*9880d681SAndroid Build Coastguard Worker        %ns1   = insertvalue {i32, {i32, i32}} %ns1.2, i32 %v2, 1, 1
22*9880d681SAndroid Build Coastguard Worker        %s2    = extractvalue {i32, {i32, i32}} %ns1, 1
23*9880d681SAndroid Build Coastguard Worker        %v3    = extractvalue {i32, {i32, i32}} %ns1, 1, 1
24*9880d681SAndroid Build Coastguard Worker        call void @bar({i32, i32} %s2)
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker        ; Use nested extractvalues to get to a value
27*9880d681SAndroid Build Coastguard Worker        %s3    = extractvalue {i32, {i32, i32}} %ns1, 1
28*9880d681SAndroid Build Coastguard Worker        %v4    = extractvalue {i32, i32} %s3, 1
29*9880d681SAndroid Build Coastguard Worker        call void @bar({i32, i32} %s3)
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker        ; Use nested insertvalues to build a nested struct
32*9880d681SAndroid Build Coastguard Worker        %s4.1 = insertvalue {i32, i32} undef, i32 %v3, 0
33*9880d681SAndroid Build Coastguard Worker        %s4   = insertvalue {i32, i32} %s4.1, i32 %v4, 1
34*9880d681SAndroid Build Coastguard Worker        %ns2  = insertvalue {i32, {i32, i32}} undef, {i32, i32} %s4, 1
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker        ; And now extract a single value from there
37*9880d681SAndroid Build Coastguard Worker        %v5   = extractvalue {i32, {i32, i32}} %ns2, 1, 1
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker        ret i32 %v5
40*9880d681SAndroid Build Coastguard Worker}
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @extract2gep(
43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[GEP:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, {{.*}}* %pair, i64 0, i32 1
44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[LOAD:%[A-Za-z0-9]+]] = load i32, i32* [[GEP]]
45*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store
46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop
47*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: extractvalue
48*9880d681SAndroid Build Coastguard Worker; CHECK: call {{.*}}(i32 [[LOAD]])
49*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: extractvalue
50*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 [[LOAD]]
51*9880d681SAndroid Build Coastguard Workerdefine i32 @extract2gep({i16, i32}* %pair, i32* %P) {
52*9880d681SAndroid Build Coastguard Worker        ; The load + extractvalue should be converted
53*9880d681SAndroid Build Coastguard Worker        ; to an inbounds gep + smaller load.
54*9880d681SAndroid Build Coastguard Worker        ; The new load should be in the same spot as the old load.
55*9880d681SAndroid Build Coastguard Worker        %L = load {i16, i32}, {i16, i32}* %pair
56*9880d681SAndroid Build Coastguard Worker        store i32 0, i32* %P
57*9880d681SAndroid Build Coastguard Worker        br label %loop
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Workerloop:
60*9880d681SAndroid Build Coastguard Worker        %E = extractvalue {i16, i32} %L, 1
61*9880d681SAndroid Build Coastguard Worker        %C = call i32 @baz(i32 %E)
62*9880d681SAndroid Build Coastguard Worker        store i32 %C, i32* %P
63*9880d681SAndroid Build Coastguard Worker        %cond = icmp eq i32 %C, 0
64*9880d681SAndroid Build Coastguard Worker        br i1 %cond, label %end, label %loop
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Workerend:
67*9880d681SAndroid Build Coastguard Worker        ret i32 %E
68*9880d681SAndroid Build Coastguard Worker}
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i16 @doubleextract2gep(
71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[GEP:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, {{.*}}* %arg, i64 0, i32 1, i32 1
72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[LOAD:%[A-Za-z0-9]+]] = load i16, i16* [[GEP]]
73*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 [[LOAD]]
74*9880d681SAndroid Build Coastguard Workerdefine i16 @doubleextract2gep({i16, {i32, i16}}* %arg) {
75*9880d681SAndroid Build Coastguard Worker        ; The load + extractvalues should be converted
76*9880d681SAndroid Build Coastguard Worker        ; to a 3-index inbounds gep + smaller load.
77*9880d681SAndroid Build Coastguard Worker        %L = load {i16, {i32, i16}}, {i16, {i32, i16}}* %arg
78*9880d681SAndroid Build Coastguard Worker        %E1 = extractvalue {i16, {i32, i16}} %L, 1
79*9880d681SAndroid Build Coastguard Worker        %E2 = extractvalue {i32, i16} %E1, 1
80*9880d681SAndroid Build Coastguard Worker        ret i16 %E2
81*9880d681SAndroid Build Coastguard Worker}
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker; CHECK: define i32 @nogep-multiuse
84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: load {{.*}} %pair
85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: extractvalue
86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: extractvalue
87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add
88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
89*9880d681SAndroid Build Coastguard Workerdefine i32 @nogep-multiuse({i32, i32}* %pair) {
90*9880d681SAndroid Build Coastguard Worker        ; The load should be left unchanged since both parts are needed.
91*9880d681SAndroid Build Coastguard Worker        %L = load volatile {i32, i32}, {i32, i32}* %pair
92*9880d681SAndroid Build Coastguard Worker        %LHS = extractvalue {i32, i32} %L, 0
93*9880d681SAndroid Build Coastguard Worker        %RHS = extractvalue {i32, i32} %L, 1
94*9880d681SAndroid Build Coastguard Worker        %R = add i32 %LHS, %RHS
95*9880d681SAndroid Build Coastguard Worker        ret i32 %R
96*9880d681SAndroid Build Coastguard Worker}
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker; CHECK: define i32 @nogep-volatile
99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: load volatile {{.*}} %pair
100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: extractvalue
101*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
102*9880d681SAndroid Build Coastguard Workerdefine i32 @nogep-volatile({i32, i32}* %pair) {
103*9880d681SAndroid Build Coastguard Worker        ; The load volatile should be left unchanged.
104*9880d681SAndroid Build Coastguard Worker        %L = load volatile {i32, i32}, {i32, i32}* %pair
105*9880d681SAndroid Build Coastguard Worker        %E = extractvalue {i32, i32} %L, 1
106*9880d681SAndroid Build Coastguard Worker        ret i32 %E
107*9880d681SAndroid Build Coastguard Worker}
108