llvm.org GIT mirror llvm / 1bfa768
[WebAssembly] Refactor load ISel tablegen patterns into classes Not all of these will be able to be used by atomics because tablegen, but it still seems like a good change by itself. Differential Revision: https://reviews.llvm.org/D37345 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312287 91177308-0d34-0410-b5e6-96231b3b80d8 Derek Schuff 3 years ago
3 changed file(s) with 217 addition(s) and 332 deletion(s). Raw diff Collapse all Expand all
1717
1818 let Defs = [ARGUMENTS] in {
1919 // TODO: add the rest of the atomic loads
20 // TODO: factor out 0xfe atomic prefix?
21 def ATOMIC_LOAD_I32 : ATOMIC_I<(outs I32:$dst),
22 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
23 [], "i32.atomic.load\t$dst, ${off}(${addr})${p2align}",
24 0xfe10>;
20 def ATOMIC_LOAD_I32 : CLoadI32<"i32.atomic.load", 0xfe10>;
21 def ATOMIC_LOAD_I64 : CLoadI64<"i64.atomic.load", 0xfe11>;
2522 } // Defs = [ARGUMENTS]
2623
2724 // Select loads with no constant offset.
2825 let Predicates = [HasAtomics] in {
29 def : Pat<(i32 (atomic_load I32:$addr)), (ATOMIC_LOAD_I32 0, 0, $addr)>;
26 class ALoadPatNoOffset :
27 Pat<(ty (node I32:$addr)), (inst 0, 0, $addr)>;
28 def : ALoadPatNoOffset;
29 def : ALoadPatNoOffset;
30
3031 }
3132
3233 //===----------------------------------------------------------------------===//
5454
5555 let Defs = [ARGUMENTS] in {
5656
57 // Classes to define both atomic and non-atomic integer loads
58 class CLoadI32 :
59 I<(outs I32:$dst),
60 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
61 [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"), Opcode>;
62
63 class CLoadI64 :
64 I<(outs I64:$dst),
65 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
66 [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"), Opcode>;
67
5768 // Basic load.
5869 // FIXME: When we can break syntax compatibility, reorder the fields in the
5970 // asmstrings to match the binary encoding.
60 def LOAD_I32 : I<(outs I32:$dst),
61 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
62 [], "i32.load\t$dst, ${off}(${addr})${p2align}", 0x28>;
63 def LOAD_I64 : I<(outs I64:$dst),
64 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
65 [], "i64.load\t$dst, ${off}(${addr})${p2align}", 0x29>;
71 def LOAD_I32 : CLoadI32<"i32.load", 0x28>;
72 def LOAD_I64 : CLoadI64<"i64.load", 0x29>;
6673 def LOAD_F32 : I<(outs F32:$dst),
6774 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
6875 [], "f32.load\t$dst, ${off}(${addr})${p2align}", 0x2a>;
7380 } // Defs = [ARGUMENTS]
7481
7582 // Select loads with no constant offset.
76 def : Pat<(i32 (load I32:$addr)), (LOAD_I32 0, 0, $addr)>;
77 def : Pat<(i64 (load I32:$addr)), (LOAD_I64 0, 0, $addr)>;
78 def : Pat<(f32 (load I32:$addr)), (LOAD_F32 0, 0, $addr)>;
79 def : Pat<(f64 (load I32:$addr)), (LOAD_F64 0, 0, $addr)>;
83 class LoadPatNoOffset :
84 Pat<(ty (node I32:$addr)), (inst 0, 0, $addr)>;
85
86 def : LoadPatNoOffset;
87 def : LoadPatNoOffset;
88 def : LoadPatNoOffset;
89 def : LoadPatNoOffset;
90
8091
8192 // Select loads with a constant offset.
82 def : Pat<(i32 (load (regPlusImm I32:$addr, imm:$off))),
83 (LOAD_I32 0, imm:$off, $addr)>;
84 def : Pat<(i64 (load (regPlusImm I32:$addr, imm:$off))),
85 (LOAD_I64 0, imm:$off, $addr)>;
86 def : Pat<(f32 (load (regPlusImm I32:$addr, imm:$off))),
87 (LOAD_F32 0, imm:$off, $addr)>;
88 def : Pat<(f64 (load (regPlusImm I32:$addr, imm:$off))),
89 (LOAD_F64 0, imm:$off, $addr)>;
90 def : Pat<(i32 (load (or_is_add I32:$addr, imm:$off))),
91 (LOAD_I32 0, imm:$off, $addr)>;
92 def : Pat<(i64 (load (or_is_add I32:$addr, imm:$off))),
93 (LOAD_I64 0, imm:$off, $addr)>;
94 def : Pat<(f32 (load (or_is_add I32:$addr, imm:$off))),
95 (LOAD_F32 0, imm:$off, $addr)>;
96 def : Pat<(f64 (load (or_is_add I32:$addr, imm:$off))),
97 (LOAD_F64 0, imm:$off, $addr)>;
98 def : Pat<(i32 (load (regPlusGA I32:$addr,
99 (WebAssemblywrapper tglobaladdr:$off)))),
100 (LOAD_I32 0, tglobaladdr:$off, $addr)>;
101 def : Pat<(i64 (load (regPlusGA I32:$addr,
102 (WebAssemblywrapper tglobaladdr:$off)))),
103 (LOAD_I64 0, tglobaladdr:$off, $addr)>;
104 def : Pat<(f32 (load (regPlusGA I32:$addr,
105 (WebAssemblywrapper tglobaladdr:$off)))),
106 (LOAD_F32 0, tglobaladdr:$off, $addr)>;
107 def : Pat<(f64 (load (regPlusGA I32:$addr,
108 (WebAssemblywrapper tglobaladdr:$off)))),
109 (LOAD_F64 0, tglobaladdr:$off, $addr)>;
110 def : Pat<(i32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
111 (LOAD_I32 0, texternalsym:$off, $addr)>;
112 def : Pat<(i64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
113 (LOAD_I64 0, texternalsym:$off, $addr)>;
114 def : Pat<(f32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
115 (LOAD_F32 0, texternalsym:$off, $addr)>;
116 def : Pat<(f64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
117 (LOAD_F64 0, texternalsym:$off, $addr)>;
93
94 // Pattern with address + immediate offset
95 class LoadPatImmOff :
96 Pat<(ty (loadkind (operand I32:$addr, imm:$off))),
97 (inst 0, imm:$off, $addr)>;
98
99 def : LoadPatImmOff;
100 def : LoadPatImmOff;
101 def : LoadPatImmOff;
102 def : LoadPatImmOff;
103 def : LoadPatImmOff;
104 def : LoadPatImmOff;
105 def : LoadPatImmOff;
106 def : LoadPatImmOff;
107
108 class LoadPatGlobalAddr :
109 Pat<(ty (loadkind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))),
110 (inst 0, tglobaladdr:$off, $addr)>;
111
112 def : LoadPatGlobalAddr;
113 def : LoadPatGlobalAddr;
114 def : LoadPatGlobalAddr;
115 def : LoadPatGlobalAddr;
116
117 class LoadPatExternalSym :
118 Pat<(ty (loadkind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
119 (inst 0, texternalsym:$off, $addr)>;
120 def : LoadPatExternalSym;
121 def : LoadPatExternalSym;
122 def : LoadPatExternalSym;
123 def : LoadPatExternalSym;
124
118125
119126 // Select loads with just a constant offset.
120 def : Pat<(i32 (load imm:$off)), (LOAD_I32 0, imm:$off, (CONST_I32 0))>;
121 def : Pat<(i64 (load imm:$off)), (LOAD_I64 0, imm:$off, (CONST_I32 0))>;
122 def : Pat<(f32 (load imm:$off)), (LOAD_F32 0, imm:$off, (CONST_I32 0))>;
123 def : Pat<(f64 (load imm:$off)), (LOAD_F64 0, imm:$off, (CONST_I32 0))>;
124 def : Pat<(i32 (load (WebAssemblywrapper tglobaladdr:$off))),
125 (LOAD_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
126 def : Pat<(i64 (load (WebAssemblywrapper tglobaladdr:$off))),
127 (LOAD_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
128 def : Pat<(f32 (load (WebAssemblywrapper tglobaladdr:$off))),
129 (LOAD_F32 0, tglobaladdr:$off, (CONST_I32 0))>;
130 def : Pat<(f64 (load (WebAssemblywrapper tglobaladdr:$off))),
131 (LOAD_F64 0, tglobaladdr:$off, (CONST_I32 0))>;
132 def : Pat<(i32 (load (WebAssemblywrapper texternalsym:$off))),
133 (LOAD_I32 0, texternalsym:$off, (CONST_I32 0))>;
134 def : Pat<(i64 (load (WebAssemblywrapper texternalsym:$off))),
135 (LOAD_I64 0, texternalsym:$off, (CONST_I32 0))>;
136 def : Pat<(f32 (load (WebAssemblywrapper texternalsym:$off))),
137 (LOAD_F32 0, texternalsym:$off, (CONST_I32 0))>;
138 def : Pat<(f64 (load (WebAssemblywrapper texternalsym:$off))),
139 (LOAD_F64 0, texternalsym:$off, (CONST_I32 0))>;
127 class LoadPatOffsetOnly :
128 Pat<(ty (loadkind imm:$off)), (inst 0, imm:$off, (CONST_I32 0))>;
129
130 def : LoadPatOffsetOnly;
131 def : LoadPatOffsetOnly;
132 def : LoadPatOffsetOnly;
133 def : LoadPatOffsetOnly;
134
135 class LoadPatGlobalAddrOffOnly :
136 Pat<(ty (loadkind (WebAssemblywrapper tglobaladdr:$off))),
137 (inst 0, tglobaladdr:$off, (CONST_I32 0))>;
138
139 def : LoadPatGlobalAddrOffOnly;
140 def : LoadPatGlobalAddrOffOnly;
141 def : LoadPatGlobalAddrOffOnly;
142 def : LoadPatGlobalAddrOffOnly;
143
144 class LoadPatExternSymOffOnly :
145 Pat<(ty (loadkind (WebAssemblywrapper texternalsym:$off))),
146 (inst 0, texternalsym:$off, (CONST_I32 0))>;
147 def : LoadPatExternSymOffOnly;
148 def : LoadPatExternSymOffOnly;
149 def : LoadPatExternSymOffOnly;
150 def : LoadPatExternSymOffOnly;
140151
141152 let Defs = [ARGUMENTS] in {
142153
175186 } // Defs = [ARGUMENTS]
176187
177188 // Select extending loads with no constant offset.
178 def : Pat<(i32 (sextloadi8 I32:$addr)), (LOAD8_S_I32 0, 0, $addr)>;
179 def : Pat<(i32 (zextloadi8 I32:$addr)), (LOAD8_U_I32 0, 0, $addr)>;
180 def : Pat<(i32 (sextloadi16 I32:$addr)), (LOAD16_S_I32 0, 0, $addr)>;
181 def : Pat<(i32 (zextloadi16 I32:$addr)), (LOAD16_U_I32 0, 0, $addr)>;
182 def : Pat<(i64 (sextloadi8 I32:$addr)), (LOAD8_S_I64 0, 0, $addr)>;
183 def : Pat<(i64 (zextloadi8 I32:$addr)), (LOAD8_U_I64 0, 0, $addr)>;
184 def : Pat<(i64 (sextloadi16 I32:$addr)), (LOAD16_S_I64 0, 0, $addr)>;
185 def : Pat<(i64 (zextloadi16 I32:$addr)), (LOAD16_U_I64 0, 0, $addr)>;
186 def : Pat<(i64 (sextloadi32 I32:$addr)), (LOAD32_S_I64 0, 0, $addr)>;
187 def : Pat<(i64 (zextloadi32 I32:$addr)), (LOAD32_U_I64 0, 0, $addr)>;
189 def : LoadPatNoOffset>;
190 def : LoadPatNoOffset;
191 def : LoadPatNoOffset;
192 def : LoadPatNoOffset;
193 def : LoadPatNoOffset;
194 def : LoadPatNoOffset;
195 def : LoadPatNoOffset;
196 def : LoadPatNoOffset;
197 def : LoadPatNoOffset;
198 def : LoadPatNoOffset;
188199
189200 // Select extending loads with a constant offset.
190 def : Pat<(i32 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
191 (LOAD8_S_I32 0, imm:$off, $addr)>;
192 def : Pat<(i32 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
193 (LOAD8_U_I32 0, imm:$off, $addr)>;
194 def : Pat<(i32 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
195 (LOAD16_S_I32 0, imm:$off, $addr)>;
196 def : Pat<(i32 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
197 (LOAD16_U_I32 0, imm:$off, $addr)>;
198 def : Pat<(i64 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
199 (LOAD8_S_I64 0, imm:$off, $addr)>;
200 def : Pat<(i64 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
201 (LOAD8_U_I64 0, imm:$off, $addr)>;
202 def : Pat<(i64 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
203 (LOAD16_S_I64 0, imm:$off, $addr)>;
204 def : Pat<(i64 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
205 (LOAD16_U_I64 0, imm:$off, $addr)>;
206 def : Pat<(i64 (sextloadi32 (regPlusImm I32:$addr, imm:$off))),
207 (LOAD32_S_I64 0, imm:$off, $addr)>;
208 def : Pat<(i64 (zextloadi32 (regPlusImm I32:$addr, imm:$off))),
209 (LOAD32_U_I64 0, imm:$off, $addr)>;
210 def : Pat<(i32 (sextloadi8 (or_is_add I32:$addr, imm:$off))),
211 (LOAD8_S_I32 0, imm:$off, $addr)>;
212 def : Pat<(i32 (zextloadi8 (or_is_add I32:$addr, imm:$off))),
213 (LOAD8_U_I32 0, imm:$off, $addr)>;
214 def : Pat<(i32 (sextloadi16 (or_is_add I32:$addr, imm:$off))),
215 (LOAD16_S_I32 0, imm:$off, $addr)>;
216 def : Pat<(i32 (zextloadi16 (or_is_add I32:$addr, imm:$off))),
217 (LOAD16_U_I32 0, imm:$off, $addr)>;
218 def : Pat<(i64 (sextloadi8 (or_is_add I32:$addr, imm:$off))),
219 (LOAD8_S_I64 0, imm:$off, $addr)>;
220 def : Pat<(i64 (zextloadi8 (or_is_add I32:$addr, imm:$off))),
221 (LOAD8_U_I64 0, imm:$off, $addr)>;
222 def : Pat<(i64 (sextloadi16 (or_is_add I32:$addr, imm:$off))),
223 (LOAD16_S_I64 0, imm:$off, $addr)>;
224 def : Pat<(i64 (zextloadi16 (or_is_add I32:$addr, imm:$off))),
225 (LOAD16_U_I64 0, imm:$off, $addr)>;
226 def : Pat<(i64 (sextloadi32 (or_is_add I32:$addr, imm:$off))),
227 (LOAD32_S_I64 0, imm:$off, $addr)>;
228 def : Pat<(i64 (zextloadi32 (or_is_add I32:$addr, imm:$off))),
229 (LOAD32_U_I64 0, imm:$off, $addr)>;
230 def : Pat<(i32 (sextloadi8 (regPlusGA I32:$addr,
231 (WebAssemblywrapper tglobaladdr:$off)))),
232 (LOAD8_S_I32 0, tglobaladdr:$off, $addr)>;
233 def : Pat<(i32 (zextloadi8 (regPlusGA I32:$addr,
234 (WebAssemblywrapper tglobaladdr:$off)))),
235 (LOAD8_U_I32 0, tglobaladdr:$off, $addr)>;
236 def : Pat<(i32 (sextloadi16 (regPlusGA I32:$addr,
237 (WebAssemblywrapper tglobaladdr:$off)))),
238 (LOAD16_S_I32 0, tglobaladdr:$off, $addr)>;
239 def : Pat<(i32 (zextloadi16 (regPlusGA I32:$addr,
240 (WebAssemblywrapper tglobaladdr:$off)))),
241 (LOAD16_U_I32 0, tglobaladdr:$off, $addr)>;
242 def : Pat<(i64 (sextloadi8 (regPlusGA I32:$addr,
243 (WebAssemblywrapper tglobaladdr:$off)))),
244 (LOAD8_S_I64 0, tglobaladdr:$off, $addr)>;
245 def : Pat<(i64 (zextloadi8 (regPlusGA I32:$addr,
246 (WebAssemblywrapper tglobaladdr:$off)))),
247 (LOAD8_U_I64 0, tglobaladdr:$off, $addr)>;
248 def : Pat<(i64 (sextloadi16 (regPlusGA I32:$addr,
249 (WebAssemblywrapper tglobaladdr:$off)))),
250 (LOAD16_S_I64 0, tglobaladdr:$off, $addr)>;
251 def : Pat<(i64 (zextloadi16 (regPlusGA I32:$addr,
252 (WebAssemblywrapper tglobaladdr:$off)))),
253 (LOAD16_U_I64 0, tglobaladdr:$off, $addr)>;
254 def : Pat<(i64 (sextloadi32 (regPlusGA I32:$addr,
255 (WebAssemblywrapper tglobaladdr:$off)))),
256 (LOAD32_S_I64 0, tglobaladdr:$off, $addr)>;
257 def : Pat<(i64 (zextloadi32 (regPlusGA I32:$addr,
258 (WebAssemblywrapper tglobaladdr:$off)))),
259 (LOAD32_U_I64 0, tglobaladdr:$off, $addr)>;
260 def : Pat<(i32 (sextloadi8 (add I32:$addr,
261 (WebAssemblywrapper texternalsym:$off)))),
262 (LOAD8_S_I32 0, texternalsym:$off, $addr)>;
263 def : Pat<(i32 (zextloadi8 (add I32:$addr,
264 (WebAssemblywrapper texternalsym:$off)))),
265 (LOAD8_U_I32 0, texternalsym:$off, $addr)>;
266 def : Pat<(i32 (sextloadi16 (add I32:$addr,
267 (WebAssemblywrapper texternalsym:$off)))),
268 (LOAD16_S_I32 0, texternalsym:$off, $addr)>;
269 def : Pat<(i32 (zextloadi16 (add I32:$addr,
270 (WebAssemblywrapper texternalsym:$off)))),
271 (LOAD16_U_I32 0, texternalsym:$off, $addr)>;
272 def : Pat<(i64 (sextloadi8 (add I32:$addr,
273 (WebAssemblywrapper texternalsym:$off)))),
274 (LOAD8_S_I64 0, texternalsym:$off, $addr)>;
275 def : Pat<(i64 (zextloadi8 (add I32:$addr,
276 (WebAssemblywrapper texternalsym:$off)))),
277 (LOAD8_U_I64 0, texternalsym:$off, $addr)>;
278 def : Pat<(i64 (sextloadi16 (add I32:$addr,
279 (WebAssemblywrapper texternalsym:$off)))),
280 (LOAD16_S_I64 0, texternalsym:$off, $addr)>;
281 def : Pat<(i64 (zextloadi16 (add I32:$addr,
282 (WebAssemblywrapper texternalsym:$off)))),
283 (LOAD16_U_I64 0, texternalsym:$off, $addr)>;
284 def : Pat<(i64 (sextloadi32 (add I32:$addr,
285 (WebAssemblywrapper texternalsym:$off)))),
286 (LOAD32_S_I64 0, texternalsym:$off, $addr)>;
287 def : Pat<(i64 (zextloadi32 (add I32:$addr,
288 (WebAssemblywrapper texternalsym:$off)))),
289 (LOAD32_U_I64 0, texternalsym:$off, $addr)>;
201 def : LoadPatImmOff>;
202 def : LoadPatImmOff;
203 def : LoadPatImmOff;
204 def : LoadPatImmOff;
205 def : LoadPatImmOff;
206 def : LoadPatImmOff;
207 def : LoadPatImmOff;
208 def : LoadPatImmOff;
209 def : LoadPatImmOff;
210 def : LoadPatImmOff;
211
212 def : LoadPatImmOff;
213 def : LoadPatImmOff;
214 def : LoadPatImmOff;
215 def : LoadPatImmOff;
216 def : LoadPatImmOff;
217 def : LoadPatImmOff;
218 def : LoadPatImmOff;
219 def : LoadPatImmOff;
220 def : LoadPatImmOff;
221 def : LoadPatImmOff;
222
223 def : LoadPatGlobalAddr;
224 def : LoadPatGlobalAddr;
225 def : LoadPatGlobalAddr;
226 def : LoadPatGlobalAddr;
227
228 def : LoadPatGlobalAddr;
229 def : LoadPatGlobalAddr;
230 def : LoadPatGlobalAddr;
231 def : LoadPatGlobalAddr;
232 def : LoadPatGlobalAddr;
233 def : LoadPatGlobalAddr;
234
235 def : LoadPatExternalSym;
236 def : LoadPatExternalSym;
237 def : LoadPatExternalSym;
238 def : LoadPatExternalSym;
239 def : LoadPatExternalSym;
240 def : LoadPatExternalSym;
241 def : LoadPatExternalSym;
242 def : LoadPatExternalSym;
243 def : LoadPatExternalSym;
244 def : LoadPatExternalSym;
245
290246
291247 // Select extending loads with just a constant offset.
292 def : Pat<(i32 (sextloadi8 imm:$off)),
293 (LOAD8_S_I32 0, imm:$off, (CONST_I32 0))>;
294 def : Pat<(i32 (zextloadi8 imm:$off)),
295 (LOAD8_U_I32 0, imm:$off, (CONST_I32 0))>;
296 def : Pat<(i32 (sextloadi16 imm:$off)),
297 (LOAD16_S_I32 0, imm:$off, (CONST_I32 0))>;
298 def : Pat<(i32 (zextloadi16 imm:$off)),
299 (LOAD16_U_I32 0, imm:$off, (CONST_I32 0))>;
300 def : Pat<(i64 (sextloadi8 imm:$off)),
301 (LOAD8_S_I64 0, imm:$off, (CONST_I32 0))>;
302 def : Pat<(i64 (zextloadi8 imm:$off)),
303 (LOAD8_U_I64 0, imm:$off, (CONST_I32 0))>;
304 def : Pat<(i64 (sextloadi16 imm:$off)),
305 (LOAD16_S_I64 0, imm:$off, (CONST_I32 0))>;
306 def : Pat<(i64 (zextloadi16 imm:$off)),
307 (LOAD16_U_I64 0, imm:$off, (CONST_I32 0))>;
308 def : Pat<(i64 (sextloadi32 imm:$off)),
309 (LOAD32_S_I64 0, imm:$off, (CONST_I32 0))>;
310 def : Pat<(i64 (zextloadi32 imm:$off)),
311 (LOAD32_U_I64 0, imm:$off, (CONST_I32 0))>;
312 def : Pat<(i32 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
313 (LOAD8_S_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
314 def : Pat<(i32 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
315 (LOAD8_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
316 def : Pat<(i32 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
317 (LOAD16_S_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
318 def : Pat<(i32 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
319 (LOAD16_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
320 def : Pat<(i64 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
321 (LOAD8_S_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
322 def : Pat<(i64 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
323 (LOAD8_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
324 def : Pat<(i64 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
325 (LOAD16_S_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
326 def : Pat<(i64 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
327 (LOAD16_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
328 def : Pat<(i64 (sextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
329 (LOAD32_S_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
330 def : Pat<(i64 (zextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
331 (LOAD32_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
332 def : Pat<(i32 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
333 (LOAD8_S_I32 0, texternalsym:$off, (CONST_I32 0))>;
334 def : Pat<(i32 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
335 (LOAD8_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
336 def : Pat<(i32 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
337 (LOAD16_S_I32 0, texternalsym:$off, (CONST_I32 0))>;
338 def : Pat<(i32 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
339 (LOAD16_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
340 def : Pat<(i64 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
341 (LOAD8_S_I64 0, texternalsym:$off, (CONST_I32 0))>;
342 def : Pat<(i64 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
343 (LOAD8_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
344 def : Pat<(i64 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
345 (LOAD16_S_I64 0, texternalsym:$off, (CONST_I32 0))>;
346 def : Pat<(i64 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
347 (LOAD16_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
348 def : Pat<(i64 (sextloadi32 (WebAssemblywrapper texternalsym:$off))),
349 (LOAD32_S_I64 0, texternalsym:$off, (CONST_I32 0))>;
350 def : Pat<(i64 (zextloadi32 (WebAssemblywrapper texternalsym:$off))),
351 (LOAD32_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
248 def : LoadPatOffsetOnly>;
249 def : LoadPatOffsetOnly;
250 def : LoadPatOffsetOnly;
251 def : LoadPatOffsetOnly;
252
253 def : LoadPatOffsetOnly;
254 def : LoadPatOffsetOnly;
255 def : LoadPatOffsetOnly;
256 def : LoadPatOffsetOnly;
257 def : LoadPatOffsetOnly;
258 def : LoadPatOffsetOnly;
259
260 def : LoadPatGlobalAddrOffOnly;
261 def : LoadPatGlobalAddrOffOnly;
262 def : LoadPatGlobalAddrOffOnly;
263 def : LoadPatGlobalAddrOffOnly;
264 def : LoadPatGlobalAddrOffOnly;
265 def : LoadPatGlobalAddrOffOnly;
266 def : LoadPatGlobalAddrOffOnly;
267 def : LoadPatGlobalAddrOffOnly;
268 def : LoadPatGlobalAddrOffOnly;
269 def : LoadPatGlobalAddrOffOnly;
270
271 def : LoadPatExternSymOffOnly;
272 def : LoadPatExternSymOffOnly;
273 def : LoadPatExternSymOffOnly;
274 def : LoadPatExternSymOffOnly;
275 def : LoadPatExternSymOffOnly;
276 def : LoadPatExternSymOffOnly;
277 def : LoadPatExternSymOffOnly;
278 def : LoadPatExternSymOffOnly;
279 def : LoadPatExternSymOffOnly;
280 def : LoadPatExternSymOffOnly;
352281
353282 // Resolve "don't care" extending loads to zero-extending loads. This is
354283 // somewhat arbitrary, but zero-extending is conceptually simpler.
355284
356285 // Select "don't care" extending loads with no constant offset.
357 def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 0, 0, $addr)>;
358 def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD16_U_I32 0, 0, $addr)>;
359 def : Pat<(i64 (extloadi8 I32:$addr)), (LOAD8_U_I64 0, 0, $addr)>;
360 def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD16_U_I64 0, 0, $addr)>;
361 def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 0, 0, $addr)>;
286 def : LoadPatNoOffset>;
287 def : LoadPatNoOffset;
288 def : LoadPatNoOffset;
289 def : LoadPatNoOffset;
290 def : LoadPatNoOffset;
291
362292
363293 // Select "don't care" extending loads with a constant offset.
364 def : Pat<(i32 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
365 (LOAD8_U_I32 0, imm:$off, $addr)>;
366 def : Pat<(i32 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
367 (LOAD16_U_I32 0, imm:$off, $addr)>;
368 def : Pat<(i64 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
369 (LOAD8_U_I64 0, imm:$off, $addr)>;
370 def : Pat<(i64 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
371 (LOAD16_U_I64 0, imm:$off, $addr)>;
372 def : Pat<(i64 (extloadi32 (regPlusImm I32:$addr, imm:$off))),
373 (LOAD32_U_I64 0, imm:$off, $addr)>;
374 def : Pat<(i32 (extloadi8 (or_is_add I32:$addr, imm:$off))),
375 (LOAD8_U_I32 0, imm:$off, $addr)>;
376 def : Pat<(i32 (extloadi16 (or_is_add I32:$addr, imm:$off))),
377 (LOAD16_U_I32 0, imm:$off, $addr)>;
378 def : Pat<(i64 (extloadi8 (or_is_add I32:$addr, imm:$off))),
379 (LOAD8_U_I64 0, imm:$off, $addr)>;
380 def : Pat<(i64 (extloadi16 (or_is_add I32:$addr, imm:$off))),
381 (LOAD16_U_I64 0, imm:$off, $addr)>;
382 def : Pat<(i64 (extloadi32 (or_is_add I32:$addr, imm:$off))),
383 (LOAD32_U_I64 0, imm:$off, $addr)>;
384 def : Pat<(i32 (extloadi8 (regPlusGA I32:$addr,
385 (WebAssemblywrapper tglobaladdr:$off)))),
386 (LOAD8_U_I32 0, tglobaladdr:$off, $addr)>;
387 def : Pat<(i32 (extloadi16 (regPlusGA I32:$addr,
388 (WebAssemblywrapper tglobaladdr:$off)))),
389 (LOAD16_U_I32 0, tglobaladdr:$off, $addr)>;
390 def : Pat<(i64 (extloadi8 (regPlusGA I32:$addr,
391 (WebAssemblywrapper tglobaladdr:$off)))),
392 (LOAD8_U_I64 0, tglobaladdr:$off, $addr)>;
393 def : Pat<(i64 (extloadi16 (regPlusGA I32:$addr,
394 (WebAssemblywrapper tglobaladdr:$off)))),
395 (LOAD16_U_I64 0, tglobaladdr:$off, $addr)>;
396 def : Pat<(i64 (extloadi32 (regPlusGA I32:$addr,
397 (WebAssemblywrapper tglobaladdr:$off)))),
398 (LOAD32_U_I64 0, tglobaladdr:$off, $addr)>;
399 def : Pat<(i32 (extloadi8 (add I32:$addr,
400 (WebAssemblywrapper texternalsym:$off)))),
401 (LOAD8_U_I32 0, texternalsym:$off, $addr)>;
402 def : Pat<(i32 (extloadi16 (add I32:$addr,
403 (WebAssemblywrapper texternalsym:$off)))),
404 (LOAD16_U_I32 0, texternalsym:$off, $addr)>;
405 def : Pat<(i64 (extloadi8 (add I32:$addr,
406 (WebAssemblywrapper texternalsym:$off)))),
407 (LOAD8_U_I64 0, texternalsym:$off, $addr)>;
408 def : Pat<(i64 (extloadi16 (add I32:$addr,
409 (WebAssemblywrapper texternalsym:$off)))),
410 (LOAD16_U_I64 0, texternalsym:$off, $addr)>;
411 def : Pat<(i64 (extloadi32 (add I32:$addr,
412 (WebAssemblywrapper texternalsym:$off)))),
413 (LOAD32_U_I64 0, texternalsym:$off, $addr)>;
294 def : LoadPatImmOff>;
295 def : LoadPatImmOff;
296 def : LoadPatImmOff;
297 def : LoadPatImmOff;
298 def : LoadPatImmOff;
299 def : LoadPatImmOff;
300 def : LoadPatImmOff;
301 def : LoadPatImmOff;
302 def : LoadPatImmOff;
303 def : LoadPatImmOff;
304 def : LoadPatGlobalAddr;
305 def : LoadPatGlobalAddr;
306 def : LoadPatGlobalAddr;
307 def : LoadPatGlobalAddr;
308 def : LoadPatGlobalAddr;
309 def : LoadPatExternalSym;
310 def : LoadPatExternalSym;
311 def : LoadPatExternalSym;
312 def : LoadPatExternalSym;
313 def : LoadPatExternalSym;
314
414315
415316 // Select "don't care" extending loads with just a constant offset.
416 def : Pat<(i32 (extloadi8 imm:$off)),
417 (LOAD8_U_I32 0, imm:$off, (CONST_I32 0))>;
418 def : Pat<(i32 (extloadi16 imm:$off)),
419 (LOAD16_U_I32 0, imm:$off, (CONST_I32 0))>;
420 def : Pat<(i64 (extloadi8 imm:$off)),
421 (LOAD8_U_I64 0, imm:$off, (CONST_I32 0))>;
422 def : Pat<(i64 (extloadi16 imm:$off)),
423 (LOAD16_U_I64 0, imm:$off, (CONST_I32 0))>;
424 def : Pat<(i64 (extloadi32 imm:$off)),
425 (LOAD32_U_I64 0, imm:$off, (CONST_I32 0))>;
426 def : Pat<(i32 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
427 (LOAD8_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
428 def : Pat<(i32 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
429 (LOAD16_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
430 def : Pat<(i64 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
431 (LOAD8_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
432 def : Pat<(i64 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
433 (LOAD16_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
434 def : Pat<(i64 (extloadi32 (WebAssemblywrapper tglobaladdr:$off))),
435 (LOAD32_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
436 def : Pat<(i32 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
437 (LOAD8_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
438 def : Pat<(i32 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
439 (LOAD16_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
440 def : Pat<(i64 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
441 (LOAD8_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
442 def : Pat<(i64 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
443 (LOAD16_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
444 def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))),
445 (LOAD32_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
317 def : LoadPatOffsetOnly>;
318 def : LoadPatOffsetOnly;
319 def : LoadPatOffsetOnly;
320 def : LoadPatOffsetOnly;
321 def : LoadPatOffsetOnly;
322 def : LoadPatGlobalAddrOffOnly;
323 def : LoadPatGlobalAddrOffOnly;
324 def : LoadPatGlobalAddrOffOnly;
325 def : LoadPatGlobalAddrOffOnly;
326 def : LoadPatGlobalAddrOffOnly;
327 def : LoadPatExternSymOffOnly;
328 def : LoadPatExternSymOffOnly;
329 def : LoadPatExternSymOffOnly;
330 def : LoadPatExternSymOffOnly;
331 def : LoadPatExternSymOffOnly;
332
446333
447334 let Defs = [ARGUMENTS] in {
448335
0 ; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=+atomics | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics | FileCheck %s
22
33 ; Test that atomic loads are assembled properly.
44
66 target triple = "wasm32-unknown-unknown-wasm"
77
88 ; CHECK-LABEL: load_i32_atomic:
9 ; CHECK-NEXT: .param i32{{$}}
10 ; CHECK-NEXT: .result i32{{$}}
11 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
12 ; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($pop[[L0]]){{$}}
9 ; CHECK: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
1310 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
1411
1512 define i32 @load_i32_atomic(i32 *%p) {