File: fix-by-val-args.ll

package info (click to toggle)
intel-graphics-compiler2 2.16.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 106,644 kB
  • sloc: cpp: 805,640; lisp: 287,672; ansic: 16,414; python: 3,952; yacc: 2,588; lex: 1,666; pascal: 313; sh: 186; makefile: 35
file content (158 lines) | stat: -rw-r--r-- 7,366 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2024 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================
;
; RUN: igc_opt --opaque-pointers --igc-legalize-function-signatures -S < %s 2>&1 | FileCheck %s
; ------------------------------------------------
; LegalizeFunctionSignatures
; ------------------------------------------------


; Pseudo-code:
; void foo(bool condition)
; {
;   st_foo a{1, 2};
;   int(*(st_foo*)) func = condition ? bar_0 : bar_1;
;   consume(func(&a));
;   consume(bar_2(&a));
;   consume(bar_3(&a));
; }
;
; void bar_0(st_foo* in)
; {
;   return in->a + in->b;
; }
;
; void bar_1(st_foo* in)
; {
;   return in->a + in->b;
; }
;
; void bar_2(st_foo* in);
;
; void bar_3(st_foo* in)
; {
;   return in->a + in->b;
; }

%struct._st_foo = type { i32, i32 }

define spir_kernel void @foo(i1 %condition) #1 {
; CHECK: define spir_kernel void @foo(i8 %condition)
; CHECK: [[CONDITION:%.*]] = trunc i8 %condition to i1
    %a = alloca %struct._st_foo
; CHECK-NEXT: [[A:%.*]] = alloca %struct._st_foo
    store %struct._st_foo { i32 1, i32 2 }, ptr %a, align 4
; CHECK-NEXT: store %struct._st_foo { i32 1, i32 2 }, ptr [[A]], align 4
    %func_addr = select i1 %condition, ptr @bar_0, ptr @bar_1
; CHECK-NEXT: [[FUNC_ADDR:%.*]] = select i1 [[CONDITION]], ptr @bar_0, ptr @bar_1
    %res_indirect = call i32 %func_addr(ptr byval(%struct._st_foo) %a)
; Prepare struct values
; CHECK-NEXT: [[MEMBER_0_ADDR_0:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A]], i32 0, i32 0
; CHECK-NEXT: [[MEMBER_0_VAL_0:%.*]] = load i32, ptr [[MEMBER_0_ADDR_0]], align 4
; CHECK-NEXT: [[STRUCT_VAL_0_0:%.*]] = insertvalue %struct._st_foo undef, i32 [[MEMBER_0_VAL_0]], 0
; CHECK-NEXT: [[MEMBER_1_ADDR_0:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A]], i32 0, i32 1
; CHECK-NEXT: [[MEMBER_1_VAL_0:%.*]] = load i32, ptr [[MEMBER_1_ADDR_0]], align 4
; CHECK-NEXT: [[STRUCT_VAL_1_0:%.*]] = insertvalue %struct._st_foo [[STRUCT_VAL_0_0]], i32 [[MEMBER_1_VAL_0]], 1
; call fixed function
; CHECK-NEXT: [[RES_VAL_0:%.*]] = call i32  [[FUNC_ADDR]](%struct._st_foo [[STRUCT_VAL_1_0]])
    call void @consume(i32 %res_indirect)
; CHECK-NEXT: call void @consume(i32 [[RES_VAL_0]])
    %res_direct_0 = call i32 @bar_2(ptr byval(%struct._st_foo) %a)
; CHECK-NEXT: %res_direct_0 = call i32 @bar_2(ptr byval(%struct._st_foo) %a)
    call void @consume(i32 %res_direct_0)
; CHECK-NEXT: call void @consume(i32 %res_direct_0)
    %res_direct_1 = call i32 @bar_3(ptr byval(%struct._st_foo) %a)
; Prepare struct values
; CHECK-NEXT: [[MEMBER_0_ADDR_1:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A]], i32 0, i32 0
; CHECK-NEXT: [[MEMBER_0_VAL_1:%.*]] = load i32, ptr [[MEMBER_0_ADDR_1]], align 4
; CHECK-NEXT: [[STRUCT_VAL_0_1:%.*]] = insertvalue %struct._st_foo undef, i32 [[MEMBER_0_VAL_1]], 0
; CHECK-NEXT: [[MEMBER_1_ADDR_1:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A]], i32 0, i32 1
; CHECK-NEXT: [[MEMBER_1_VAL_1:%.*]] = load i32, ptr [[MEMBER_1_ADDR_1]], align 4
; CHECK-NEXT: [[STRUCT_VAL_1_1:%.*]] = insertvalue %struct._st_foo [[STRUCT_VAL_0_1]], i32 [[MEMBER_1_VAL_1]], 1
; call fixed function
; CHECK-NEXT: [[RES_VAL_1:%.*]] = call i32 @bar_3(%struct._st_foo [[STRUCT_VAL_1_1]])
    call void @consume(i32 %res_direct_1)
; CHECK-NEXT: call void @consume(i32 [[RES_VAL_1]])

    ret void
}

define internal spir_func i32 @bar_0(ptr byval(%struct._st_foo) %s) #1 {
; CHECK: define internal spir_func i32 @bar_0(%struct._st_foo [[ARG_0:%.*]])
entry:
; an internal variable
; CHECK: [[A_0:%.*]] = alloca %struct._st_foo, align 8
; store the argument to the internal variable
; CHECK-NEXT: [[B0_MEMBER_0_ADDR:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 0
; CHECK-NEXT: [[B0_MEMBER_0_VAL:%.*]] = extractvalue %struct._st_foo [[ARG_0]], 0
; CHECK-NEXT: store i32 [[B0_MEMBER_0_VAL]], ptr [[B0_MEMBER_0_ADDR]], align 4
; CHECK-NEXT: [[B0_MEMBER_1_ADDR:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 1
; CHECK-NEXT: [[B0_MEMBER_1_VAL:%.*]] = extractvalue %struct._st_foo [[ARG_0]], 1
; CHECK-NEXT: store i32 [[B0_MEMBER_1_VAL]], ptr [[B0_MEMBER_1_ADDR]], align 4
  %a = getelementptr inbounds %struct._st_foo, ptr %s, i32 0, i32 0
; CHECK: %a = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 0
  %0 = load i32, ptr %a, align 4
  %b = getelementptr inbounds %struct._st_foo, ptr %s, i32 0, i32 1
; CHECK: %b = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 1
  %1 = load i32, ptr %b, align 4
  %add = add nsw i32 %0, %1
  ret i32 %add
}

define internal spir_func i32 @bar_1(ptr byval(%struct._st_foo) %s) #2 {
; CHECK: define internal spir_func i32 @bar_1(%struct._st_foo [[ARG_1:%.*]])
entry:
; an internal variable
; CHECK: [[A_1:%.*]] = alloca %struct._st_foo, align 8
; store the argument to the internal variable
; CHECK-NEXT: [[B1_MEMBER_0_ADDR:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A_1]], i32 0, i32 0
; CHECK-NEXT: [[B1_MEMBER_0_VAL:%.*]] = extractvalue %struct._st_foo [[ARG_1]], 0
; CHECK-NEXT: store i32 [[B1_MEMBER_0_VAL]], ptr [[B1_MEMBER_0_ADDR]], align 4
; CHECK-NEXT: [[B1_MEMBER_1_ADDR:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A_1]], i32 0, i32 1
; CHECK-NEXT: [[B1_MEMBER_1_VAL:%.*]] = extractvalue %struct._st_foo [[ARG_1]], 1
; CHECK-NEXT: store i32 [[B1_MEMBER_1_VAL]], ptr [[B1_MEMBER_1_ADDR]], align 4
  %a = getelementptr inbounds %struct._st_foo, ptr %s, i32 0, i32 0
; CHECK: %a = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 0
  %0 = load i32, ptr %a, align 4
  %b = getelementptr inbounds %struct._st_foo, ptr %s, i32 0, i32 1
; CHECK: %b = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 1
  %1 = load i32, ptr %b, align 4
  %add = add nsw i32 %0, %1
  ret i32 %add
}

declare spir_func i32 @bar_2(ptr byval(%struct._st_foo) %s) #0

define internal spir_func i32 @bar_3(ptr byval(%struct._st_foo) %s) {
; CHECK: define internal spir_func i32 @bar_3(%struct._st_foo [[ARG_3:%.*]])
entry:
; an internal variable
; CHECK: [[A_3:%.*]] = alloca %struct._st_foo, align 8
; store the argument to the internal variable
; CHECK-NEXT: [[B3_MEMBER_0_ADDR:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A_3]], i32 0, i32 0
; CHECK-NEXT: [[B3_MEMBER_0_VAL:%.*]] = extractvalue %struct._st_foo [[ARG_3]], 0
; CHECK-NEXT: store i32 [[B3_MEMBER_0_VAL]], ptr [[B3_MEMBER_0_ADDR]], align 4
; CHECK-NEXT: [[B3_MEMBER_1_ADDR:%.*]] = getelementptr inbounds %struct._st_foo, ptr [[A_3]], i32 0, i32 1
; CHECK-NEXT: [[B3_MEMBER_1_VAL:%.*]] = extractvalue %struct._st_foo [[ARG_3]], 1
; CHECK-NEXT: store i32 [[B3_MEMBER_1_VAL]], ptr [[B3_MEMBER_1_ADDR]], align 4
  %a = getelementptr inbounds %struct._st_foo, ptr %s, i32 0, i32 0
; CHECK: %a = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 0
  %0 = load i32, ptr %a, align 4
  %b = getelementptr inbounds %struct._st_foo, ptr %s, i32 0, i32 1
; CHECK: %b = getelementptr inbounds %struct._st_foo, ptr [[A_0]], i32 0, i32 1
  %1 = load i32, ptr %b, align 4
  %add = add nsw i32 %0, %1
  ret i32 %add
}

declare spir_func void @consume(i32)


attributes #0 = { "visaStackCall" }
attributes #1 = { "referenced-indirectly" }
attributes #2 = { "referenced-indirectly" "visaStackCall" }