llvm.org GIT mirror llvm / 37a984b
[WebAssembly] Massive instruction renaming Summary: An automated renaming of all the instructions listed at https://github.com/WebAssembly/spec/issues/884#issuecomment-426433329 as well as some similarly-named identifiers. Reviewers: aheejin, dschuff, aardappel Subscribers: sbc100, jgravelle-google, eraman, sunfish, jfb, llvm-commits Differential Revision: https://reviews.llvm.org/D56338 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350609 91177308-0d34-0410-b5e6-96231b3b80d8 Thomas Lively 7 months ago
71 changed file(s) with 984 addition(s) and 984 deletion(s). Raw diff Collapse all Expand all
210210 WASM_TYPE_F32 = 0x7D,
211211 WASM_TYPE_F64 = 0x7C,
212212 WASM_TYPE_V128 = 0x7B,
213 WASM_TYPE_ANYFUNC = 0x70,
213 WASM_TYPE_FUNCREF = 0x70,
214214 WASM_TYPE_EXCEPT_REF = 0x68,
215215 WASM_TYPE_FUNC = 0x60,
216216 WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
228228 // Opcodes used in initializer expressions.
229229 enum : unsigned {
230230 WASM_OPCODE_END = 0x0b,
231 WASM_OPCODE_GET_GLOBAL = 0x23,
231 WASM_OPCODE_GLOBAL_GET = 0x23,
232232 WASM_OPCODE_I32_CONST = 0x41,
233233 WASM_OPCODE_I64_CONST = 0x42,
234234 WASM_OPCODE_F32_CONST = 0x43,
11751175 TableImport.Module = TableSym->getModuleName();
11761176 TableImport.Field = TableSym->getName();
11771177 TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
1178 TableImport.Table.ElemType = wasm::WASM_TYPE_ANYFUNC;
1178 TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
11791179 Imports.push_back(TableImport);
11801180
11811181 // Populate SignatureIndices, and Imports and WasmIndices for undefined
175175 case wasm::WASM_OPCODE_F64_CONST:
176176 Expr.Value.Float64 = readFloat64(Ctx);
177177 break;
178 case wasm::WASM_OPCODE_GET_GLOBAL:
178 case wasm::WASM_OPCODE_GLOBAL_GET:
179179 Expr.Value.Global = readULEB128(Ctx);
180180 break;
181181 default:
818818 break;
819819 case wasm::WASM_EXTERNAL_TABLE:
820820 Im.Table = readTable(Ctx);
821 if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC)
821 if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF)
822822 return make_error("Invalid table element type",
823823 object_error::parse_failed);
824824 break;
861861 Tables.reserve(Count);
862862 while (Count--) {
863863 Tables.push_back(readTable(Ctx));
864 if (Tables.back().ElemType != wasm::WASM_TYPE_ANYFUNC) {
864 if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF) {
865865 return make_error("Invalid table element type",
866866 object_error::parse_failed);
867867 }
376376 case wasm::WASM_OPCODE_F64_CONST:
377377 IO.mapRequired("Value", Expr.Value.Float64);
378378 break;
379 case wasm::WASM_OPCODE_GET_GLOBAL:
379 case wasm::WASM_OPCODE_GLOBAL_GET:
380380 IO.mapRequired("Index", Expr.Value.Global);
381381 break;
382382 }
490490 ECase(F32);
491491 ECase(F64);
492492 ECase(V128);
493 ECase(ANYFUNC);
493 ECase(FUNCREF);
494494 ECase(FUNC);
495495 ECase(NORESULT);
496496 #undef ECase
515515 ECase(I64_CONST);
516516 ECase(F64_CONST);
517517 ECase(F32_CONST);
518 ECase(GET_GLOBAL);
518 ECase(GLOBAL_GET);
519519 #undef ECase
520520 }
521521
522522 void ScalarEnumerationTraits::enumeration(
523523 IO &IO, WasmYAML::TableType &Type) {
524524 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
525 ECase(ANYFUNC);
525 ECase(FUNCREF);
526526 #undef ECase
527527 }
528528
3939 void WebAssemblyInstPrinter::printRegName(raw_ostream &OS,
4040 unsigned RegNo) const {
4141 assert(RegNo != WebAssemblyFunctionInfo::UnusedReg);
42 // Note that there's an implicit get_local/set_local here!
42 // Note that there's an implicit local.get/local.set here!
4343 OS << "$" << RegNo;
4444 }
4545
291291 return "f64";
292292 case wasm::WASM_TYPE_V128:
293293 return "v128";
294 case wasm::WASM_TYPE_ANYFUNC:
295 return "anyfunc";
294 case wasm::WASM_TYPE_FUNCREF:
295 return "funcref";
296296 case wasm::WASM_TYPE_FUNC:
297297 return "func";
298298 case wasm::WASM_TYPE_EXCEPT_REF:
119119 It could be done with a smaller encoding like this:
120120
121121 i32.const $push5=, 0
122 tee_local $push6=, $4=, $pop5
123 copy_local $3=, $pop6
122 local.tee $push6=, $4=, $pop5
123 local.copy $3=, $pop6
124124
125125 //===---------------------------------------------------------------------===//
126126
179179 //===---------------------------------------------------------------------===//
180180
181181 The function @dynamic_alloca_redzone in test/CodeGen/WebAssembly/userstack.ll
182 ends up with a tee_local in its prolog which has an unused result, requiring
182 ends up with a local.tee in its prolog which has an unused result, requiring
183183 an extra drop:
184184
185 get_global $push8=, 0
186 tee_local $push9=, 1, $pop8
185 global.get $push8=, 0
186 local.tee $push9=, 1, $pop8
187187 drop $pop9
188188 [...]
189189
1010 /// This file converts any remaining registers into WebAssembly locals.
1111 ///
1212 /// After register stackification and register coloring, convert non-stackified
13 /// registers into locals, inserting explicit get_local and set_local
13 /// registers into locals, inserting explicit local.get and local.set
1414 /// instructions.
1515 ///
1616 //===----------------------------------------------------------------------===//
9595 llvm_unreachable("Unexpected register class");
9696 }
9797
98 /// Get the appropriate get_local opcode for the given register class.
98 /// Get the appropriate local.get opcode for the given register class.
9999 static unsigned getGetLocalOpcode(const TargetRegisterClass *RC) {
100100 if (RC == &WebAssembly::I32RegClass)
101 return WebAssembly::GET_LOCAL_I32;
101 return WebAssembly::LOCAL_GET_I32;
102102 if (RC == &WebAssembly::I64RegClass)
103 return WebAssembly::GET_LOCAL_I64;
103 return WebAssembly::LOCAL_GET_I64;
104104 if (RC == &WebAssembly::F32RegClass)
105 return WebAssembly::GET_LOCAL_F32;
105 return WebAssembly::LOCAL_GET_F32;
106106 if (RC == &WebAssembly::F64RegClass)
107 return WebAssembly::GET_LOCAL_F64;
107 return WebAssembly::LOCAL_GET_F64;
108108 if (RC == &WebAssembly::V128RegClass)
109 return WebAssembly::GET_LOCAL_V128;
109 return WebAssembly::LOCAL_GET_V128;
110110 if (RC == &WebAssembly::EXCEPT_REFRegClass)
111 return WebAssembly::GET_LOCAL_EXCEPT_REF;
111 return WebAssembly::LOCAL_GET_EXCEPT_REF;
112112 llvm_unreachable("Unexpected register class");
113113 }
114114
115 /// Get the appropriate set_local opcode for the given register class.
115 /// Get the appropriate local.set opcode for the given register class.
116116 static unsigned getSetLocalOpcode(const TargetRegisterClass *RC) {
117117 if (RC == &WebAssembly::I32RegClass)
118 return WebAssembly::SET_LOCAL_I32;
118 return WebAssembly::LOCAL_SET_I32;
119119 if (RC == &WebAssembly::I64RegClass)
120 return WebAssembly::SET_LOCAL_I64;
120 return WebAssembly::LOCAL_SET_I64;
121121 if (RC == &WebAssembly::F32RegClass)
122 return WebAssembly::SET_LOCAL_F32;
122 return WebAssembly::LOCAL_SET_F32;
123123 if (RC == &WebAssembly::F64RegClass)
124 return WebAssembly::SET_LOCAL_F64;
124 return WebAssembly::LOCAL_SET_F64;
125125 if (RC == &WebAssembly::V128RegClass)
126 return WebAssembly::SET_LOCAL_V128;
126 return WebAssembly::LOCAL_SET_V128;
127127 if (RC == &WebAssembly::EXCEPT_REFRegClass)
128 return WebAssembly::SET_LOCAL_EXCEPT_REF;
128 return WebAssembly::LOCAL_SET_EXCEPT_REF;
129129 llvm_unreachable("Unexpected register class");
130130 }
131131
132 /// Get the appropriate tee_local opcode for the given register class.
132 /// Get the appropriate local.tee opcode for the given register class.
133133 static unsigned getTeeLocalOpcode(const TargetRegisterClass *RC) {
134134 if (RC == &WebAssembly::I32RegClass)
135 return WebAssembly::TEE_LOCAL_I32;
135 return WebAssembly::LOCAL_TEE_I32;
136136 if (RC == &WebAssembly::I64RegClass)
137 return WebAssembly::TEE_LOCAL_I64;
137 return WebAssembly::LOCAL_TEE_I64;
138138 if (RC == &WebAssembly::F32RegClass)
139 return WebAssembly::TEE_LOCAL_F32;
139 return WebAssembly::LOCAL_TEE_F32;
140140 if (RC == &WebAssembly::F64RegClass)
141 return WebAssembly::TEE_LOCAL_F64;
141 return WebAssembly::LOCAL_TEE_F64;
142142 if (RC == &WebAssembly::V128RegClass)
143 return WebAssembly::TEE_LOCAL_V128;
143 return WebAssembly::LOCAL_TEE_V128;
144144 if (RC == &WebAssembly::EXCEPT_REFRegClass)
145 return WebAssembly::TEE_LOCAL_EXCEPT_REF;
145 return WebAssembly::LOCAL_TEE_EXCEPT_REF;
146146 llvm_unreachable("Unexpected register class");
147147 }
148148
232232 if (MI.isDebugInstr() || MI.isLabel())
233233 continue;
234234
235 // Replace tee instructions with tee_local. The difference is that tee
236 // instructions have two defs, while tee_local instructions have one def
235 // Replace tee instructions with local.tee. The difference is that tee
236 // instructions have two defs, while local.tee instructions have one def
237237 // and an index of a local to write to.
238238 if (WebAssembly::isTee(MI)) {
239239 assert(MFI.isVRegStackified(MI.getOperand(0).getReg()));
252252 MFI.stackifyVReg(NewReg);
253253 }
254254
255 // Replace the TEE with a TEE_LOCAL.
255 // Replace the TEE with a LOCAL_TEE.
256256 unsigned LocalId =
257257 getLocalId(Reg2Local, CurLocal, MI.getOperand(1).getReg());
258258 unsigned Opc = getTeeLocalOpcode(RC);
266266 continue;
267267 }
268268
269 // Insert set_locals for any defs that aren't stackified yet. Currently
269 // Insert local.sets for any defs that aren't stackified yet. Currently
270270 // we handle at most one def.
271271 assert(MI.getDesc().getNumDefs() <= 1);
272272 if (MI.getDesc().getNumDefs() == 1) {
296296 }
297297 MI.getOperand(0).setReg(NewReg);
298298 // This register operand of the original instruction is now being used
299 // by the inserted drop or set_local instruction, so make it not dead
299 // by the inserted drop or local.set instruction, so make it not dead
300300 // yet.
301301 MI.getOperand(0).setIsDead(false);
302302 MFI.stackifyVReg(NewReg);
304304 }
305305 }
306306
307 // Insert get_locals for any uses that aren't stackified yet.
307 // Insert local.gets for any uses that aren't stackified yet.
308308 MachineInstr *InsertPt = &MI;
309309 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
310310 if (!MO.isReg())
326326 }
327327
328328 // If we see a stackified register, prepare to insert subsequent
329 // get_locals before the start of its tree.
329 // local.gets before the start of its tree.
330330 if (MFI.isVRegStackified(OldReg)) {
331331 InsertPt = findStartOfTree(MO, MRI, MFI);
332332 continue;
342342 continue;
343343 }
344344
345 // Insert a get_local.
345 // Insert a local.get.
346346 unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
347347 const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
348348 unsigned NewReg = MRI.createVirtualRegister(RC);
129129
130130 const char *ES = "__stack_pointer";
131131 auto *SPSymbol = MF.createExternalSymbolName(ES);
132 BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::SET_GLOBAL_I32))
132 BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::GLOBAL_SET_I32))
133133 .addExternalSymbol(SPSymbol, WebAssemblyII::MO_SYMBOL_GLOBAL)
134134 .addReg(SrcReg);
135135 }
176176
177177 const char *ES = "__stack_pointer";
178178 auto *SPSymbol = MF.createExternalSymbolName(ES);
179 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg)
179 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GLOBAL_GET_I32), SPReg)
180180 .addExternalSymbol(SPSymbol, WebAssemblyII::MO_SYMBOL_GLOBAL);
181181
182182 bool HasBP = hasBP(MF);
916916 // the FI to some LEA-like instruction, but since we don't have that, we
917917 // need to insert some kind of instruction that can take an FI operand and
918918 // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
919 // copy_local between Op and its FI operand.
919 // local.copy between Op and its FI operand.
920920 SDValue Chain = Op.getOperand(0);
921921 SDLoc DL(Op);
922922 unsigned Reg = cast(Op.getOperand(1))->getReg();
113113 def : LoadPatNoOffset;
114114 def : LoadPatNoOffset;
115115 def : LoadPatNoOffset;
116 // 32->64 sext load gets selected as i32.atomic.load, i64.extend_s/i32
116 // 32->64 sext load gets selected as i32.atomic.load, i64.extend_i32_s
117117
118118 // Zero-extending loads with constant offset
119119 def : LoadPatImmOff;
343343 defm ATOMIC_RMW_ADD_I32 : WebAssemblyBinRMW;
344344 defm ATOMIC_RMW_ADD_I64 : WebAssemblyBinRMW;
345345 defm ATOMIC_RMW8_U_ADD_I32 :
346 WebAssemblyBinRMW_u.add", 0xfe20>;
346 WebAssemblyBinRMW.add_u", 0xfe20>;
347347 defm ATOMIC_RMW16_U_ADD_I32 :
348 WebAssemblyBinRMW_u.add", 0xfe21>;
348 WebAssemblyBinRMW.add_u", 0xfe21>;
349349 defm ATOMIC_RMW8_U_ADD_I64 :
350 WebAssemblyBinRMW_u.add", 0xfe22>;
350 WebAssemblyBinRMW.add_u", 0xfe22>;
351351 defm ATOMIC_RMW16_U_ADD_I64 :
352 WebAssemblyBinRMW_u.add", 0xfe23>;
352 WebAssemblyBinRMW.add_u", 0xfe23>;
353353 defm ATOMIC_RMW32_U_ADD_I64 :
354 WebAssemblyBinRMW_u.add", 0xfe24>;
354 WebAssemblyBinRMW.add_u", 0xfe24>;
355355
356356 defm ATOMIC_RMW_SUB_I32 : WebAssemblyBinRMW;
357357 defm ATOMIC_RMW_SUB_I64 : WebAssemblyBinRMW;
358358 defm ATOMIC_RMW8_U_SUB_I32 :
359 WebAssemblyBinRMW_u.sub", 0xfe27>;
359 WebAssemblyBinRMW.sub_u", 0xfe27>;
360360 defm ATOMIC_RMW16_U_SUB_I32 :
361 WebAssemblyBinRMW_u.sub", 0xfe28>;
361 WebAssemblyBinRMW.sub_u", 0xfe28>;
362362 defm ATOMIC_RMW8_U_SUB_I64 :
363 WebAssemblyBinRMW_u.sub", 0xfe29>;
363 WebAssemblyBinRMW.sub_u", 0xfe29>;
364364 defm ATOMIC_RMW16_U_SUB_I64 :
365 WebAssemblyBinRMW_u.sub", 0xfe2a>;
365 WebAssemblyBinRMW.sub_u", 0xfe2a>;
366366 defm ATOMIC_RMW32_U_SUB_I64 :
367 WebAssemblyBinRMW_u.sub", 0xfe2b>;
367 WebAssemblyBinRMW.sub_u", 0xfe2b>;
368368
369369 defm ATOMIC_RMW_AND_I32 : WebAssemblyBinRMW;
370370 defm ATOMIC_RMW_AND_I64 : WebAssemblyBinRMW;
371371 defm ATOMIC_RMW8_U_AND_I32 :
372 WebAssemblyBinRMW_u.and", 0xfe2e>;
372 WebAssemblyBinRMW.and_u", 0xfe2e>;
373373 defm ATOMIC_RMW16_U_AND_I32 :
374 WebAssemblyBinRMW_u.and", 0xfe2f>;
374 WebAssemblyBinRMW.and_u", 0xfe2f>;
375375 defm ATOMIC_RMW8_U_AND_I64 :
376 WebAssemblyBinRMW_u.and", 0xfe30>;
376 WebAssemblyBinRMW.and_u", 0xfe30>;
377377 defm ATOMIC_RMW16_U_AND_I64 :
378 WebAssemblyBinRMW_u.and", 0xfe31>;
378 WebAssemblyBinRMW.and_u", 0xfe31>;
379379 defm ATOMIC_RMW32_U_AND_I64 :
380 WebAssemblyBinRMW_u.and", 0xfe32>;
380 WebAssemblyBinRMW.and_u", 0xfe32>;
381381
382382 defm ATOMIC_RMW_OR_I32 : WebAssemblyBinRMW;
383383 defm ATOMIC_RMW_OR_I64 : WebAssemblyBinRMW;
384384 defm ATOMIC_RMW8_U_OR_I32 :
385 WebAssemblyBinRMW_u.or", 0xfe35>;
385 WebAssemblyBinRMW.or_u", 0xfe35>;
386386 defm ATOMIC_RMW16_U_OR_I32 :
387 WebAssemblyBinRMW_u.or", 0xfe36>;
387 WebAssemblyBinRMW.or_u", 0xfe36>;
388388 defm ATOMIC_RMW8_U_OR_I64 :
389 WebAssemblyBinRMW_u.or", 0xfe37>;
389 WebAssemblyBinRMW.or_u", 0xfe37>;
390390 defm ATOMIC_RMW16_U_OR_I64 :
391 WebAssemblyBinRMW_u.or", 0xfe38>;
391 WebAssemblyBinRMW.or_u", 0xfe38>;
392392 defm ATOMIC_RMW32_U_OR_I64 :
393 WebAssemblyBinRMW_u.or", 0xfe39>;
393 WebAssemblyBinRMW.or_u", 0xfe39>;
394394
395395 defm ATOMIC_RMW_XOR_I32 : WebAssemblyBinRMW;
396396 defm ATOMIC_RMW_XOR_I64 : WebAssemblyBinRMW;
397397 defm ATOMIC_RMW8_U_XOR_I32 :
398 WebAssemblyBinRMW_u.xor", 0xfe3c>;
398 WebAssemblyBinRMW.xor_u", 0xfe3c>;
399399 defm ATOMIC_RMW16_U_XOR_I32 :
400 WebAssemblyBinRMW_u.xor", 0xfe3d>;
400 WebAssemblyBinRMW.xor_u", 0xfe3d>;
401401 defm ATOMIC_RMW8_U_XOR_I64 :
402 WebAssemblyBinRMW_u.xor", 0xfe3e>;
402 WebAssemblyBinRMW.xor_u", 0xfe3e>;
403403 defm ATOMIC_RMW16_U_XOR_I64 :
404 WebAssemblyBinRMW_u.xor", 0xfe3f>;
404 WebAssemblyBinRMW.xor_u", 0xfe3f>;
405405 defm ATOMIC_RMW32_U_XOR_I64 :
406 WebAssemblyBinRMW_u.xor", 0xfe40>;
406 WebAssemblyBinRMW.xor_u", 0xfe40>;
407407
408408 defm ATOMIC_RMW_XCHG_I32 :
409409 WebAssemblyBinRMW;
410410 defm ATOMIC_RMW_XCHG_I64 :
411411 WebAssemblyBinRMW;
412412 defm ATOMIC_RMW8_U_XCHG_I32 :
413 WebAssemblyBinRMW_u.xchg", 0xfe43>;
413 WebAssemblyBinRMW.xchg_u", 0xfe43>;
414414 defm ATOMIC_RMW16_U_XCHG_I32 :
415 WebAssemblyBinRMW_u.xchg", 0xfe44>;
415 WebAssemblyBinRMW.xchg_u", 0xfe44>;
416416 defm ATOMIC_RMW8_U_XCHG_I64 :
417 WebAssemblyBinRMW_u.xchg", 0xfe45>;
417 WebAssemblyBinRMW.xchg_u", 0xfe45>;
418418 defm ATOMIC_RMW16_U_XCHG_I64 :
419 WebAssemblyBinRMW_u.xchg", 0xfe46>;
419 WebAssemblyBinRMW.xchg_u", 0xfe46>;
420420 defm ATOMIC_RMW32_U_XCHG_I64 :
421 WebAssemblyBinRMW_u.xchg", 0xfe47>;
421 WebAssemblyBinRMW.xchg_u", 0xfe47>;
422422
423423 // Select binary RMWs with no constant offset.
424424 class BinRMWPatNoOffset :
529529 PatFrag<(ops node:$addr, node:$val),
530530 (anyext (i32 (kind node:$addr, (i32 (trunc (i64 node:$val))))))>;
531531 class sext_bin_rmw_16_64 : sext_bin_rmw_8_64;
532 // 32->64 sext RMW gets selected as i32.atomic.rmw.***, i64.extend_s/i32
532 // 32->64 sext RMW gets selected as i32.atomic.rmw.***, i64.extend_i32_s
533533
534534 // Patterns for various addressing modes for truncating-extending binary RMWs.
535535 multiclass BinRMWTruncExtPattern<
676676 defm ATOMIC_RMW_CMPXCHG_I64 :
677677 WebAssemblyTerRMW;
678678 defm ATOMIC_RMW8_U_CMPXCHG_I32 :
679 WebAssemblyTerRMW_u.cmpxchg", 0xfe4a>;
679 WebAssemblyTerRMW.cmpxchg_u", 0xfe4a>;
680680 defm ATOMIC_RMW16_U_CMPXCHG_I32 :
681 WebAssemblyTerRMW_u.cmpxchg", 0xfe4b>;
681 WebAssemblyTerRMW.cmpxchg_u", 0xfe4b>;
682682 defm ATOMIC_RMW8_U_CMPXCHG_I64 :
683 WebAssemblyTerRMW_u.cmpxchg", 0xfe4c>;
683 WebAssemblyTerRMW.cmpxchg_u", 0xfe4c>;
684684 defm ATOMIC_RMW16_U_CMPXCHG_I64 :
685 WebAssemblyTerRMW_u.cmpxchg", 0xfe4d>;
685 WebAssemblyTerRMW.cmpxchg_u", 0xfe4d>;
686686 defm ATOMIC_RMW32_U_CMPXCHG_I64 :
687 WebAssemblyTerRMW_u.cmpxchg", 0xfe4e>;
687 WebAssemblyTerRMW.cmpxchg_u", 0xfe4e>;
688688
689689 // Select ternary RMWs with no constant offset.
690690 class TerRMWPatNoOffset :
789789 (i32 (trunc (i64 node:$exp))),
790790 (i32 (trunc (i64 node:$new))))))))>;
791791 class sext_ter_rmw_16_64 : sext_ter_rmw_8_64;
792 // 32->64 sext RMW gets selected as i32.atomic.rmw.***, i64.extend_s/i32
792 // 32->64 sext RMW gets selected as i32.atomic.rmw.***, i64.extend_i32_s
793793
794794 // Patterns for various addressing modes for truncating-extending ternary RMWs.
795795 multiclass TerRMWTruncExtPattern<
1414
1515 defm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins),
1616 [(set I32:$dst, (trunc I64:$src))],
17 "i32.wrap/i64\t$dst, $src", "i32.wrap/i64", 0xa7>;
17 "i32.wrap_i64\t$dst, $src", "i32.wrap_i64", 0xa7>;
1818
1919 defm I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins),
2020 [(set I64:$dst, (sext I32:$src))],
21 "i64.extend_s/i32\t$dst, $src", "i64.extend_s/i32",
21 "i64.extend_i32_s\t$dst, $src", "i64.extend_i32_s",
2222 0xac>;
2323 defm I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins),
2424 [(set I64:$dst, (zext I32:$src))],
25 "i64.extend_u/i32\t$dst, $src", "i64.extend_u/i32",
25 "i64.extend_i32_u\t$dst, $src", "i64.extend_i32_u",
2626 0xad>;
2727
2828 let Predicates = [HasSignExt] in {
5757 // overflow or invalid.
5858 defm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
5959 [(set I32:$dst, (fp_to_sint F32:$src))],
60 "i32.trunc_s:sat/f32\t$dst, $src",
61 "i32.trunc_s:sat/f32", 0xfc00>,
60 "i32.trunc_sat_f32_s\t$dst, $src",
61 "i32.trunc_sat_f32_s", 0xfc00>,
6262 Requires<[HasNontrappingFPToInt]>;
6363 defm I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
6464 [(set I32:$dst, (fp_to_uint F32:$src))],
65 "i32.trunc_u:sat/f32\t$dst, $src",
66 "i32.trunc_u:sat/f32", 0xfc01>,
65 "i32.trunc_sat_f32_u\t$dst, $src",
66 "i32.trunc_sat_f32_u", 0xfc01>,
6767 Requires<[HasNontrappingFPToInt]>;
6868 defm I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
6969 [(set I64:$dst, (fp_to_sint F32:$src))],
70 "i64.trunc_s:sat/f32\t$dst, $src",
71 "i64.trunc_s:sat/f32", 0xfc04>,
70 "i64.trunc_sat_f32_s\t$dst, $src",
71 "i64.trunc_sat_f32_s", 0xfc04>,
7272 Requires<[HasNontrappingFPToInt]>;
7373 defm I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
7474 [(set I64:$dst, (fp_to_uint F32:$src))],
75 "i64.trunc_u:sat/f32\t$dst, $src",
76 "i64.trunc_u:sat/f32", 0xfc05>,
75 "i64.trunc_sat_f32_u\t$dst, $src",
76 "i64.trunc_sat_f32_u", 0xfc05>,
7777 Requires<[HasNontrappingFPToInt]>;
7878 defm I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
7979 [(set I32:$dst, (fp_to_sint F64:$src))],
80 "i32.trunc_s:sat/f64\t$dst, $src",
81 "i32.trunc_s:sat/f64", 0xfc02>,
80 "i32.trunc_sat_f64_s\t$dst, $src",
81 "i32.trunc_sat_f64_s", 0xfc02>,
8282 Requires<[HasNontrappingFPToInt]>;
8383 defm I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
8484 [(set I32:$dst, (fp_to_uint F64:$src))],
85 "i32.trunc_u:sat/f64\t$dst, $src",
86 "i32.trunc_u:sat/f64", 0xfc03>,
85 "i32.trunc_sat_f64_u\t$dst, $src",
86 "i32.trunc_sat_f64_u", 0xfc03>,
8787 Requires<[HasNontrappingFPToInt]>;
8888 defm I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
8989 [(set I64:$dst, (fp_to_sint F64:$src))],
90 "i64.trunc_s:sat/f64\t$dst, $src",
91 "i64.trunc_s:sat/f64", 0xfc06>,
90 "i64.trunc_sat_f64_s\t$dst, $src",
91 "i64.trunc_sat_f64_s", 0xfc06>,
9292 Requires<[HasNontrappingFPToInt]>;
9393 defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
9494 [(set I64:$dst, (fp_to_uint F64:$src))],
95 "i64.trunc_u:sat/f64\t$dst, $src",
96 "i64.trunc_u:sat/f64", 0xfc07>,
95 "i64.trunc_sat_f64_u\t$dst, $src",
96 "i64.trunc_sat_f64_u", 0xfc07>,
9797 Requires<[HasNontrappingFPToInt]>;
9898
9999 // Lower llvm.wasm.trunc.saturate.* to saturating instructions
146146 // Conversion from floating point to integer traps on overflow and invalid.
147147 let hasSideEffects = 1 in {
148148 defm I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
149 [], "i32.trunc_s/f32\t$dst, $src", "i32.trunc_s/f32",
149 [], "i32.trunc_f32_s\t$dst, $src", "i32.trunc_f32_s",
150150 0xa8>;
151151 defm I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
152 [], "i32.trunc_u/f32\t$dst, $src", "i32.trunc_u/f32",
152 [], "i32.trunc_f32_u\t$dst, $src", "i32.trunc_f32_u",
153153 0xa9>;
154154 defm I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
155 [], "i64.trunc_s/f32\t$dst, $src", "i64.trunc_s/f32",
155 [], "i64.trunc_f32_s\t$dst, $src", "i64.trunc_f32_s",
156156 0xae>;
157157 defm I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
158 [], "i64.trunc_u/f32\t$dst, $src", "i64.trunc_u/f32",
158 [], "i64.trunc_f32_u\t$dst, $src", "i64.trunc_f32_u",
159159 0xaf>;
160160 defm I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
161 [], "i32.trunc_s/f64\t$dst, $src", "i32.trunc_s/f64",
161 [], "i32.trunc_f64_s\t$dst, $src", "i32.trunc_f64_s",
162162 0xaa>;
163163 defm I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
164 [], "i32.trunc_u/f64\t$dst, $src", "i32.trunc_u/f64",
164 [], "i32.trunc_f64_u\t$dst, $src", "i32.trunc_f64_u",
165165 0xab>;
166166 defm I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
167 [], "i64.trunc_s/f64\t$dst, $src", "i64.trunc_s/f64",
167 [], "i64.trunc_f64_s\t$dst, $src", "i64.trunc_f64_s",
168168 0xb0>;
169169 defm I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
170 [], "i64.trunc_u/f64\t$dst, $src", "i64.trunc_u/f64",
170 [], "i64.trunc_f64_u\t$dst, $src", "i64.trunc_f64_u",
171171 0xb1>;
172172 } // hasSideEffects = 1
173173
174174 defm F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
175175 [(set F32:$dst, (sint_to_fp I32:$src))],
176 "f32.convert_s/i32\t$dst, $src", "f32.convert_s/i32",
176 "f32.convert_i32_s\t$dst, $src", "f32.convert_i32_s",
177177 0xb2>;
178178 defm F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
179179 [(set F32:$dst, (uint_to_fp I32:$src))],
180 "f32.convert_u/i32\t$dst, $src", "f32.convert_u/i32",
180 "f32.convert_i32_u\t$dst, $src", "f32.convert_i32_u",
181181 0xb3>;
182182 defm F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins),
183183 [(set F64:$dst, (sint_to_fp I32:$src))],
184 "f64.convert_s/i32\t$dst, $src", "f64.convert_s/i32",
184 "f64.convert_i32_s\t$dst, $src", "f64.convert_i32_s",
185185 0xb7>;
186186 defm F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins),
187187 [(set F64:$dst, (uint_to_fp I32:$src))],
188 "f64.convert_u/i32\t$dst, $src", "f64.convert_u/i32",
188 "f64.convert_i32_u\t$dst, $src", "f64.convert_i32_u",
189189 0xb8>;
190190 defm F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins),
191191 [(set F32:$dst, (sint_to_fp I64:$src))],
192 "f32.convert_s/i64\t$dst, $src", "f32.convert_s/i64",
192 "f32.convert_i64_s\t$dst, $src", "f32.convert_i64_s",
193193 0xb4>;
194194 defm F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins),
195195 [(set F32:$dst, (uint_to_fp I64:$src))],
196 "f32.convert_u/i64\t$dst, $src", "f32.convert_u/i64",
196 "f32.convert_i64_u\t$dst, $src", "f32.convert_i64_u",
197197 0xb5>;
198198 defm F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
199199 [(set F64:$dst, (sint_to_fp I64:$src))],
200 "f64.convert_s/i64\t$dst, $src", "f64.convert_s/i64",
200 "f64.convert_i64_s\t$dst, $src", "f64.convert_i64_s",
201201 0xb9>;
202202 defm F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
203203 [(set F64:$dst, (uint_to_fp I64:$src))],
204 "f64.convert_u/i64\t$dst, $src", "f64.convert_u/i64",
204 "f64.convert_i64_u\t$dst, $src", "f64.convert_i64_u",
205205 0xba>;
206206
207207 defm F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), (outs), (ins),
208208 [(set F64:$dst, (fpextend F32:$src))],
209 "f64.promote/f32\t$dst, $src", "f64.promote/f32",
209 "f64.promote_f32\t$dst, $src", "f64.promote_f32",
210210 0xbb>;
211211 defm F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), (outs), (ins),
212212 [(set F32:$dst, (fpround F64:$src))],
213 "f32.demote/f64\t$dst, $src", "f32.demote/f64",
213 "f32.demote_f64\t$dst, $src", "f32.demote_f64",
214214 0xb6>;
215215
216216 defm I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
217217 [(set I32:$dst, (bitconvert F32:$src))],
218 "i32.reinterpret/f32\t$dst, $src",
219 "i32.reinterpret/f32", 0xbc>;
218 "i32.reinterpret_f32\t$dst, $src",
219 "i32.reinterpret_f32", 0xbc>;
220220 defm F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
221221 [(set F32:$dst, (bitconvert I32:$src))],
222 "f32.reinterpret/i32\t$dst, $src",
223 "f32.reinterpret/i32", 0xbe>;
222 "f32.reinterpret_i32\t$dst, $src",
223 "f32.reinterpret_i32", 0xbe>;
224224 defm I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
225225 [(set I64:$dst, (bitconvert F64:$src))],
226 "i64.reinterpret/f64\t$dst, $src",
227 "i64.reinterpret/f64", 0xbd>;
226 "i64.reinterpret_f64\t$dst, $src",
227 "i64.reinterpret_f64", 0xbd>;
228228 defm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
229229 [(set F64:$dst, (bitconvert I64:$src))],
230 "f64.reinterpret/i64\t$dst, $src",
231 "f64.reinterpret/i64", 0xbf>;
230 "f64.reinterpret_i64\t$dst, $src",
231 "f64.reinterpret_i64", 0xbf>;
3939 // based version of this instruction, as well as the corresponding asmstr.
4040 // The register versions have virtual-register operands which correspond to wasm
4141 // locals or stack locations. Each use and def of the register corresponds to an
42 // implicit get_local / set_local or access of stack operands in wasm. These
42 // implicit local.get / local.set or access of stack operands in wasm. These
4343 // instructions are used for ISel and all MI passes. The stack versions of the
4444 // instructions do not have register operands (they implicitly operate on the
45 // stack), and get_locals and set_locals are explicit. The register instructions
45 // stack), and local.gets and local.sets are explicit. The register instructions
4646 // are converted to their corresponding stack instructions before lowering to
4747 // MC.
4848 // Every instruction should want to be based on this multi-class to guarantee
196196 defm "": ARGUMENT;
197197 defm "": ARGUMENT;
198198
199 // get_local and set_local are not generated by instruction selection; they
199 // local.get and local.set are not generated by instruction selection; they
200200 // are implied by virtual register uses and defs.
201201 multiclass LOCAL {
202202 let hasSideEffects = 0 in {
203 // COPY is not an actual instruction in wasm, but since we allow get_local and
204 // set_local to be implicit during most of codegen, we can have a COPY which
205 // is actually a no-op because all the work is done in the implied get_local
206 // and set_local. COPYs are eliminated (and replaced with
207 // get_local/set_local) in the ExplicitLocals pass.
203 // COPY is not an actual instruction in wasm, but since we allow local.get and
204 // local.set to be implicit during most of codegen, we can have a COPY which
205 // is actually a no-op because all the work is done in the implied local.get
206 // and local.set. COPYs are eliminated (and replaced with
207 // local.get/local.set) in the ExplicitLocals pass.
208208 let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
209209 defm COPY_#vt : I<(outs vt:$res), (ins vt:$src), (outs), (ins), [],
210 "copy_local\t$res, $src", "copy_local">;
210 "local.copy\t$res, $src", "local.copy">;
211211
212212 // TEE is similar to COPY, but writes two copies of its result. Typically
213213 // this would be used to stackify one result and write the other result to a
214214 // local.
215215 let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
216216 defm TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), (outs), (ins), [],
217 "tee_local\t$res, $also, $src", "tee_local">;
218
219 // This is the actual get_local instruction in wasm. These are made explicit
217 "local.tee\t$res, $also, $src", "local.tee">;
218
219 // This is the actual local.get instruction in wasm. These are made explicit
220220 // by the ExplicitLocals pass. It has mayLoad because it reads from a wasm
221221 // local, which is a side effect not otherwise modeled in LLVM.
222222 let mayLoad = 1, isAsCheapAsAMove = 1 in
223 defm GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local),
223 defm LOCAL_GET_#vt : I<(outs vt:$res), (ins local_op:$local),
224224 (outs), (ins local_op:$local), [],
225 "get_local\t$res, $local", "get_local\t$local", 0x20>;
226
227 // This is the actual set_local instruction in wasm. These are made explicit
225 "local.get\t$res, $local", "local.get\t$local", 0x20>;
226
227 // This is the actual local.set instruction in wasm. These are made explicit
228228 // by the ExplicitLocals pass. It has mayStore because it writes to a wasm
229229 // local, which is a side effect not otherwise modeled in LLVM.
230230 let mayStore = 1, isAsCheapAsAMove = 1 in
231 defm SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src),
231 defm LOCAL_SET_#vt : I<(outs), (ins local_op:$local, vt:$src),
232232 (outs), (ins local_op:$local), [],
233 "set_local\t$local, $src", "set_local\t$local", 0x21>;
234
235 // This is the actual tee_local instruction in wasm. TEEs are turned into
236 // TEE_LOCALs by the ExplicitLocals pass. It has mayStore for the same reason
237 // as SET_LOCAL.
233 "local.set\t$local, $src", "local.set\t$local", 0x21>;
234
235 // This is the actual local.tee instruction in wasm. TEEs are turned into
236 // LOCAL_TEEs by the ExplicitLocals pass. It has mayStore for the same reason
237 // as LOCAL_SET.
238238 let mayStore = 1, isAsCheapAsAMove = 1 in
239 defm TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src),
239 defm LOCAL_TEE_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src),
240240 (outs), (ins local_op:$local), [],
241 "tee_local\t$res, $local, $src", "tee_local\t$local",
241 "local.tee\t$res, $local, $src", "local.tee\t$local",
242242 0x22>;
243243
244244 // Unused values must be dropped in some contexts.
246246 "drop\t$src", "drop", 0x1a>;
247247
248248 let mayLoad = 1 in
249 defm GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local),
249 defm GLOBAL_GET_#vt : I<(outs vt:$res), (ins global_op:$local),
250250 (outs), (ins global_op:$local), [],
251 "get_global\t$res, $local", "get_global\t$local",
251 "global.get\t$res, $local", "global.get\t$local",
252252 0x23>;
253253
254254 let mayStore = 1 in
255 defm SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src),
255 defm GLOBAL_SET_#vt : I<(outs), (ins global_op:$local, vt:$src),
256256 (outs), (ins global_op:$local), [],
257 "set_global\t$local, $src", "set_global\t$local",
257 "global.set\t$local, $src", "global.set\t$local",
258258 0x24>;
259259
260260 } // hasSideEffects = 0
772772 name#"\t$dst, $vec", name, simdop>;
773773 }
774774
775 // Integer to floating point: convert_s / convert_u
776 defm "" : SIMDConvert;
777 defm "" : SIMDConvert;
778 defm "" : SIMDConvert;
779 defm "" : SIMDConvert;
780
781 // Floating point to integer with saturation: trunc_sat_s / trunc_sat_u
782 defm "" : SIMDConvert;
783 defm "" : SIMDConvert;
784 defm "" : SIMDConvert;
785 defm "" : SIMDConvert;
775 // Integer to floating point: convert
776 defm "" : SIMDConvert;
777 defm "" : SIMDConvert;
778 defm "" : SIMDConvert;
779 defm "" : SIMDConvert;
780
781 // Floating point to integer with saturation: trunc_sat
782 defm "" : SIMDConvert;
783 defm "" : SIMDConvert;
784 defm "" : SIMDConvert;
785 defm "" : SIMDConvert;
786786
787787 // Lower llvm.wasm.trunc.saturate.* to saturating instructions
788788 def : Pat<(v4i32 (int_wasm_trunc_saturate_signed (v4f32 V128:$src))),
286286 // %exn = catch 0
287287 // call @__clang_call_terminate(%exn)
288288 // unreachable
289 // (There can be set_local and get_locals before the call if we didn't run
289 // (There can be local.set and local.gets before the call if we didn't run
290290 // RegStackify)
291291 // But code transformations can change or add more control flow, so the call to
292292 // __clang_call_terminate() function may not be in the original EH pad anymore.
325325 // This runs after hoistCatches(), so catch instruction should be at the top
326326 assert(WebAssembly::isCatch(*Catch));
327327 // Takes the result register of the catch instruction as argument. There may
328 // have been some other set_local/get_locals in between, but at this point
328 // have been some other local.set/local.gets in between, but at this point
329329 // we don't care.
330330 Call->getOperand(1).setReg(Catch->getOperand(0).getReg());
331331 auto InsertPos = std::next(MachineBasicBlock::iterator(Catch));
424424 // Actually, dominating is over-conservative. Test that the use would
425425 // happen after the one selected use in the stack evaluation order.
426426 //
427 // This is needed as a consequence of using implicit get_locals for
428 // uses and implicit set_locals for defs.
427 // This is needed as a consequence of using implicit local.gets for
428 // uses and implicit local.sets for defs.
429429 if (UseInst->getDesc().getNumDefs() == 0)
430430 return false;
431431 const MachineOperand &MO = UseInst->getOperand(0);
627627 /// INST ..., Reg, ...
628628 /// INST ..., Reg, ...
629629 ///
630 /// with DefReg and TeeReg stackified. This eliminates a get_local from the
630 /// with DefReg and TeeReg stackified. This eliminates a local.get from the
631631 /// resulting code.
632632 static MachineInstr *MoveAndTeeForMultiUse(
633633 unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB,
738738 /// operand in the tree that we haven't visited yet. Moving a definition of
739739 /// Reg to a point in the tree after that would change its value.
740740 ///
741 /// This is needed as a consequence of using implicit get_locals for
742 /// uses and implicit set_locals for defs.
741 /// This is needed as a consequence of using implicit local.gets for
742 /// uses and implicit local.sets for defs.
743743 bool IsOnStack(unsigned Reg) const {
744744 for (const RangeTy &Range : Worklist)
745745 for (const MachineOperand &MO : Range)
1414 /// the store's result value, making the stored value register more likely to
1515 /// be single-use, thus more likely to be useful to register stackifying, and
1616 /// potentially also exposing the store to register stackifying. These both can
17 /// reduce get_local/set_local traffic.
17 /// reduce local.get/local.set traffic.
1818 ///
1919 /// This pass also performs this optimization for memcpy, memmove, and memset
2020 /// calls, since the LLVM intrinsics for these return void so they can't use the
325325 addPass(createWebAssemblyRegColoring());
326326 }
327327
328 // Insert explicit get_local and set_local operators.
328 // Insert explicit local.get and local.set operators.
329329 addPass(createWebAssemblyExplicitLocals());
330330
331331 // Sort the blocks of the CFG into topological order, a prerequisite for
275275
276276 ; CHECK-LABEL: add_sext_i8_i32:
277277 ; CHECK-NEXT: .functype add_sext_i8_i32 (i32, i32) -> (i32){{$}}
278 ; CHECK: i32.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
278 ; CHECK: i32.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
279279 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
280280 ; CHECK-NEXT: return $pop1{{$}}
281281 define i32 @add_sext_i8_i32(i8* %p, i32 %v) {
287287
288288 ; CHECK-LABEL: add_sext_i16_i32:
289289 ; CHECK-NEXT: .functype add_sext_i16_i32 (i32, i32) -> (i32){{$}}
290 ; CHECK: i32.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
290 ; CHECK: i32.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
291291 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
292292 ; CHECK-NEXT: return $pop1{{$}}
293293 define i32 @add_sext_i16_i32(i16* %p, i32 %v) {
299299
300300 ; CHECK-LABEL: add_sext_i8_i64:
301301 ; CHECK-NEXT: .functype add_sext_i8_i64 (i32, i64) -> (i64){{$}}
302 ; CHECK: i64.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
302 ; CHECK: i64.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
303303 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
304304 ; CHECK-NEXT: return $pop1{{$}}
305305 define i64 @add_sext_i8_i64(i8* %p, i64 %v) {
311311
312312 ; CHECK-LABEL: add_sext_i16_i64:
313313 ; CHECK-NEXT: .functype add_sext_i16_i64 (i32, i64) -> (i64){{$}}
314 ; CHECK: i64.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
314 ; CHECK: i64.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
315315 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
316316 ; CHECK-NEXT: return $pop1{{$}}
317317 define i64 @add_sext_i16_i64(i16* %p, i64 %v) {
321321 ret i64 %e
322322 }
323323
324 ; 32->64 sext rmw gets selected as i32.atomic.rmw.add, i64_extend_s/i32
324 ; 32->64 sext rmw gets selected as i32.atomic.rmw.add, i64.extend_i32_s
325325 ; CHECK-LABEL: add_sext_i32_i64:
326326 ; CHECK-NEXT: .functype add_sext_i32_i64 (i32, i64) -> (i64){{$}}
327 ; CHECK: i32.wrap/i64 $push0=, $1{{$}}
327 ; CHECK: i32.wrap_i64 $push0=, $1{{$}}
328328 ; CHECK: i32.atomic.rmw.add $push1=, 0($0), $pop0{{$}}
329 ; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
329 ; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
330330 ; CHECK-NEXT: return $pop2{{$}}
331331 define i64 @add_sext_i32_i64(i32* %p, i64 %v) {
332332 %t = trunc i64 %v to i32
339339
340340 ; CHECK-LABEL: sub_sext_i8_i32:
341341 ; CHECK-NEXT: .functype sub_sext_i8_i32 (i32, i32) -> (i32){{$}}
342 ; CHECK: i32.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
342 ; CHECK: i32.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
343343 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
344344 ; CHECK-NEXT: return $pop1{{$}}
345345 define i32 @sub_sext_i8_i32(i8* %p, i32 %v) {
351351
352352 ; CHECK-LABEL: sub_sext_i16_i32:
353353 ; CHECK-NEXT: .functype sub_sext_i16_i32 (i32, i32) -> (i32){{$}}
354 ; CHECK: i32.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
354 ; CHECK: i32.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
355355 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
356356 ; CHECK-NEXT: return $pop1{{$}}
357357 define i32 @sub_sext_i16_i32(i16* %p, i32 %v) {
363363
364364 ; CHECK-LABEL: sub_sext_i8_i64:
365365 ; CHECK-NEXT: .functype sub_sext_i8_i64 (i32, i64) -> (i64){{$}}
366 ; CHECK: i64.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
366 ; CHECK: i64.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
367367 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
368368 ; CHECK-NEXT: return $pop1{{$}}
369369 define i64 @sub_sext_i8_i64(i8* %p, i64 %v) {
375375
376376 ; CHECK-LABEL: sub_sext_i16_i64:
377377 ; CHECK-NEXT: .functype sub_sext_i16_i64 (i32, i64) -> (i64){{$}}
378 ; CHECK: i64.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
378 ; CHECK: i64.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
379379 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
380380 ; CHECK-NEXT: return $pop1{{$}}
381381 define i64 @sub_sext_i16_i64(i16* %p, i64 %v) {
385385 ret i64 %e
386386 }
387387
388 ; 32->64 sext rmw gets selected as i32.atomic.rmw.sub, i64_extend_s/i32
388 ; 32->64 sext rmw gets selected as i32.atomic.rmw.sub, i64.extend_i32_s
389389 ; CHECK-LABEL: sub_sext_i32_i64:
390390 ; CHECK-NEXT: .functype sub_sext_i32_i64 (i32, i64) -> (i64){{$}}
391 ; CHECK: i32.wrap/i64 $push0=, $1
391 ; CHECK: i32.wrap_i64 $push0=, $1
392392 ; CHECK: i32.atomic.rmw.sub $push1=, 0($0), $pop0{{$}}
393 ; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
393 ; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
394394 ; CHECK-NEXT: return $pop2{{$}}
395395 define i64 @sub_sext_i32_i64(i32* %p, i64 %v) {
396396 %t = trunc i64 %v to i32
403403
404404 ; CHECK-LABEL: and_sext_i8_i32:
405405 ; CHECK-NEXT: .functype and_sext_i8_i32 (i32, i32) -> (i32){{$}}
406 ; CHECK: i32.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
406 ; CHECK: i32.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
407407 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
408408 ; CHECK-NEXT: return $pop1{{$}}
409409 define i32 @and_sext_i8_i32(i8* %p, i32 %v) {
415415
416416 ; CHECK-LABEL: and_sext_i16_i32:
417417 ; CHECK-NEXT: .functype and_sext_i16_i32 (i32, i32) -> (i32){{$}}
418 ; CHECK: i32.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
418 ; CHECK: i32.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
419419 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
420420 ; CHECK-NEXT: return $pop1{{$}}
421421 define i32 @and_sext_i16_i32(i16* %p, i32 %v) {
427427
428428 ; CHECK-LABEL: and_sext_i8_i64:
429429 ; CHECK-NEXT: .functype and_sext_i8_i64 (i32, i64) -> (i64){{$}}
430 ; CHECK: i64.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
430 ; CHECK: i64.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
431431 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
432432 ; CHECK-NEXT: return $pop1{{$}}
433433 define i64 @and_sext_i8_i64(i8* %p, i64 %v) {
439439
440440 ; CHECK-LABEL: and_sext_i16_i64:
441441 ; CHECK-NEXT: .functype and_sext_i16_i64 (i32, i64) -> (i64){{$}}
442 ; CHECK: i64.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
442 ; CHECK: i64.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
443443 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
444444 ; CHECK-NEXT: return $pop1{{$}}
445445 define i64 @and_sext_i16_i64(i16* %p, i64 %v) {
449449 ret i64 %e
450450 }
451451
452 ; 32->64 sext rmw gets selected as i32.atomic.rmw.and, i64_extend_s/i32
452 ; 32->64 sext rmw gets selected as i32.atomic.rmw.and, i64.extend_i32_s
453453 ; CHECK-LABEL: and_sext_i32_i64:
454454 ; CHECK-NEXT: .functype and_sext_i32_i64 (i32, i64) -> (i64){{$}}
455 ; CHECK: i32.wrap/i64 $push0=, $1{{$}}
455 ; CHECK: i32.wrap_i64 $push0=, $1{{$}}
456456 ; CHECK: i32.atomic.rmw.and $push1=, 0($0), $pop0{{$}}
457 ; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
457 ; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
458458 ; CHECK-NEXT: return $pop2{{$}}
459459 define i64 @and_sext_i32_i64(i32* %p, i64 %v) {
460460 %t = trunc i64 %v to i32
467467
468468 ; CHECK-LABEL: or_sext_i8_i32:
469469 ; CHECK-NEXT: .functype or_sext_i8_i32 (i32, i32) -> (i32){{$}}
470 ; CHECK: i32.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
470 ; CHECK: i32.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
471471 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
472472 ; CHECK-NEXT: return $pop1{{$}}
473473 define i32 @or_sext_i8_i32(i8* %p, i32 %v) {
479479
480480 ; CHECK-LABEL: or_sext_i16_i32:
481481 ; CHECK-NEXT: .functype or_sext_i16_i32 (i32, i32) -> (i32){{$}}
482 ; CHECK: i32.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
482 ; CHECK: i32.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
483483 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
484484 ; CHECK-NEXT: return $pop1{{$}}
485485 define i32 @or_sext_i16_i32(i16* %p, i32 %v) {
491491
492492 ; CHECK-LABEL: or_sext_i8_i64:
493493 ; CHECK-NEXT: .functype or_sext_i8_i64 (i32, i64) -> (i64){{$}}
494 ; CHECK: i64.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
494 ; CHECK: i64.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
495495 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
496496 ; CHECK-NEXT: return $pop1{{$}}
497497 define i64 @or_sext_i8_i64(i8* %p, i64 %v) {
503503
504504 ; CHECK-LABEL: or_sext_i16_i64:
505505 ; CHECK-NEXT: .functype or_sext_i16_i64 (i32, i64) -> (i64){{$}}
506 ; CHECK: i64.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
506 ; CHECK: i64.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
507507 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
508508 ; CHECK-NEXT: return $pop1{{$}}
509509 define i64 @or_sext_i16_i64(i16* %p, i64 %v) {
513513 ret i64 %e
514514 }
515515
516 ; 32->64 sext rmw gets selected as i32.atomic.rmw.or, i64_extend_s/i32
516 ; 32->64 sext rmw gets selected as i32.atomic.rmw.or, i64.extend_i32_s
517517 ; CHECK-LABEL: or_sext_i32_i64:
518518 ; CHECK-NEXT: .functype or_sext_i32_i64 (i32, i64) -> (i64){{$}}
519 ; CHECK: i32.wrap/i64 $push0=, $1{{$}}
519 ; CHECK: i32.wrap_i64 $push0=, $1{{$}}
520520 ; CHECK: i32.atomic.rmw.or $push1=, 0($0), $pop0{{$}}
521 ; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
521 ; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
522522 ; CHECK-NEXT: return $pop2{{$}}
523523 define i64 @or_sext_i32_i64(i32* %p, i64 %v) {
524524 %t = trunc i64 %v to i32
531531
532532 ; CHECK-LABEL: xor_sext_i8_i32:
533533 ; CHECK-NEXT: .functype xor_sext_i8_i32 (i32, i32) -> (i32){{$}}
534 ; CHECK: i32.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
534 ; CHECK: i32.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
535535 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
536536 ; CHECK-NEXT: return $pop1{{$}}
537537 define i32 @xor_sext_i8_i32(i8* %p, i32 %v) {
543543
544544 ; CHECK-LABEL: xor_sext_i16_i32:
545545 ; CHECK-NEXT: .functype xor_sext_i16_i32 (i32, i32) -> (i32){{$}}
546 ; CHECK: i32.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
546 ; CHECK: i32.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
547547 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
548548 ; CHECK-NEXT: return $pop1{{$}}
549549 define i32 @xor_sext_i16_i32(i16* %p, i32 %v) {
555555
556556 ; CHECK-LABEL: xor_sext_i8_i64:
557557 ; CHECK-NEXT: .functype xor_sext_i8_i64 (i32, i64) -> (i64){{$}}
558 ; CHECK: i64.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
558 ; CHECK: i64.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
559559 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
560560 ; CHECK-NEXT: return $pop1{{$}}
561561 define i64 @xor_sext_i8_i64(i8* %p, i64 %v) {
567567
568568 ; CHECK-LABEL: xor_sext_i16_i64:
569569 ; CHECK-NEXT: .functype xor_sext_i16_i64 (i32, i64) -> (i64){{$}}
570 ; CHECK: i64.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
570 ; CHECK: i64.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
571571 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
572572 ; CHECK-NEXT: return $pop1{{$}}
573573 define i64 @xor_sext_i16_i64(i16* %p, i64 %v) {
577577 ret i64 %e
578578 }
579579
580 ; 32->64 sext rmw gets selected as i32.atomic.rmw.xor, i64_extend_s/i32
580 ; 32->64 sext rmw gets selected as i32.atomic.rmw.xor, i64.extend_i32_s
581581 ; CHECK-LABEL: xor_sext_i32_i64:
582582 ; CHECK-NEXT: .functype xor_sext_i32_i64 (i32, i64) -> (i64){{$}}
583 ; CHECK: i32.wrap/i64 $push0=, $1{{$}}
583 ; CHECK: i32.wrap_i64 $push0=, $1{{$}}
584584 ; CHECK: i32.atomic.rmw.xor $push1=, 0($0), $pop0{{$}}
585 ; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
585 ; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
586586 ; CHECK-NEXT: return $pop2{{$}}
587587 define i64 @xor_sext_i32_i64(i32* %p, i64 %v) {
588588 %t = trunc i64 %v to i32
595595
596596 ; CHECK-LABEL: xchg_sext_i8_i32:
597597 ; CHECK-NEXT: .functype xchg_sext_i8_i32 (i32, i32) -> (i32){{$}}
598 ; CHECK: i32.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
598 ; CHECK: i32.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
599599 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
600600 ; CHECK-NEXT: return $pop1{{$}}
601601 define i32 @xchg_sext_i8_i32(i8* %p, i32 %v) {
607607
608608 ; CHECK-LABEL: xchg_sext_i16_i32:
609609 ; CHECK-NEXT: .functype xchg_sext_i16_i32 (i32, i32) -> (i32){{$}}
610 ; CHECK: i32.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
610 ; CHECK: i32.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
611611 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
612612 ; CHECK-NEXT: return $pop1{{$}}
613613 define i32 @xchg_sext_i16_i32(i16* %p, i32 %v) {
619619
620620 ; CHECK-LABEL: xchg_sext_i8_i64:
621621 ; CHECK-NEXT: .functype xchg_sext_i8_i64 (i32, i64) -> (i64){{$}}
622 ; CHECK: i64.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
622 ; CHECK: i64.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
623623 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
624624 ; CHECK-NEXT: return $pop1{{$}}
625625 define i64 @xchg_sext_i8_i64(i8* %p, i64 %v) {
631631
632632 ; CHECK-LABEL: xchg_sext_i16_i64:
633633 ; CHECK-NEXT: .functype xchg_sext_i16_i64 (i32, i64) -> (i64){{$}}
634 ; CHECK: i64.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
634 ; CHECK: i64.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
635635 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
636636 ; CHECK-NEXT: return $pop1{{$}}
637637 define i64 @xchg_sext_i16_i64(i16* %p, i64 %v) {
641641 ret i64 %e
642642 }
643643
644 ; 32->64 sext rmw gets selected as i32.atomic.rmw.xchg, i64_extend_s/i32
644 ; 32->64 sext rmw gets selected as i32.atomic.rmw.xchg, i64.extend_i32_s
645645 ; CHECK-LABEL: xchg_sext_i32_i64:
646646 ; CHECK-NEXT: .functype xchg_sext_i32_i64 (i32, i64) -> (i64){{$}}
647 ; CHECK: i32.wrap/i64 $push0=, $1{{$}}
647 ; CHECK: i32.wrap_i64 $push0=, $1{{$}}
648648 ; CHECK: i32.atomic.rmw.xchg $push1=, 0($0), $pop0{{$}}
649 ; CHECK-NEXT: i64.extend_s/i32 $push2=, $pop1{{$}}
649 ; CHECK-NEXT: i64.extend_i32_s $push2=, $pop1{{$}}
650650 ; CHECK-NEXT: return $pop2{{$}}
651651 define i64 @xchg_sext_i32_i64(i32* %p, i64 %v) {
652652 %t = trunc i64 %v to i32
659659
660660 ; CHECK-LABEL: cmpxchg_sext_i8_i32:
661661 ; CHECK-NEXT: .functype cmpxchg_sext_i8_i32 (i32, i32, i32) -> (i32){{$}}
662 ; CHECK: i32.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
662 ; CHECK: i32.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
663663 ; CHECK-NEXT: i32.extend8_s $push1=, $pop0{{$}}
664664 ; CHECK-NEXT: return $pop1{{$}}
665665 define i32 @cmpxchg_sext_i8_i32(i8* %p, i32 %exp, i32 %new) {
673673
674674 ; CHECK-LABEL: cmpxchg_sext_i16_i32:
675675 ; CHECK-NEXT: .functype cmpxchg_sext_i16_i32 (i32, i32, i32) -> (i32){{$}}
676 ; CHECK: i32.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
676 ; CHECK: i32.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
677677 ; CHECK-NEXT: i32.extend16_s $push1=, $pop0{{$}}
678678 ; CHECK-NEXT: return $pop1{{$}}
679679 define i32 @cmpxchg_sext_i16_i32(i16* %p, i32 %exp, i32 %new) {
687687
688688 ; CHECK-LABEL: cmpxchg_sext_i8_i64:
689689 ; CHECK-NEXT: .functype cmpxchg_sext_i8_i64 (i32, i64, i64) -> (i64){{$}}
690 ; CHECK: i64.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
690 ; CHECK: i64.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
691691 ; CHECK-NEXT: i64.extend8_s $push1=, $pop0{{$}}
692692 ; CHECK-NEXT: return $pop1{{$}}
693693 define i64 @cmpxchg_sext_i8_i64(i8* %p, i64 %exp, i64 %new) {
701701
702702 ; CHECK-LABEL: cmpxchg_sext_i16_i64:
703703 ; CHECK-NEXT: .functype cmpxchg_sext_i16_i64 (i32, i64, i64) -> (i64){{$}}
704 ; CHECK: i64.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
704 ; CHECK: i64.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
705705 ; CHECK-NEXT: i64.extend16_s $push1=, $pop0{{$}}
706706 ; CHECK-NEXT: return $pop1{{$}}
707707 define i64 @cmpxchg_sext_i16_i64(i16* %p, i64 %exp, i64 %new) {
713713 ret i64 %e
714714 }
715715
716 ; 32->64 sext rmw gets selected as i32.atomic.rmw.cmpxchg, i64_extend_s/i32
716 ; 32->64 sext rmw gets selected as i32.atomic.rmw.cmpxchg, i64.extend_i32_s
717717 ; CHECK-LABEL: cmpxchg_sext_i32_i64:
718718 ; CHECK-NEXT: .functype cmpxchg_sext_i32_i64 (i32, i64, i64) -> (i64){{$}}
719 ; CHECK: i32.wrap/i64 $push1=, $1{{$}}
720 ; CHECK-NEXT: i32.wrap/i64 $push0=, $2{{$}}
719 ; CHECK: i32.wrap_i64 $push1=, $1{{$}}
720 ; CHECK-NEXT: i32.wrap_i64 $push0=, $2{{$}}
721721 ; CHECK-NEXT: i32.atomic.rmw.cmpxchg $push2=, 0($0), $pop1, $pop0{{$}}
722 ; CHECK-NEXT: i64.extend_s/i32 $push3=, $pop2{{$}}
722 ; CHECK-NEXT: i64.extend_i32_s $push3=, $pop2{{$}}
723723 ; CHECK-NEXT: return $pop3{{$}}
724724 define i64 @cmpxchg_sext_i32_i64(i32* %p, i64 %exp, i64 %new) {
725725 %exp_t = trunc i64 %exp to i32
738738 ; CHECK-LABEL: nand_sext_i8_i32:
739739 ; CHECK-NEXT: .functype nand_sext_i8_i32 (i32, i32) -> (i32){{$}}
740740 ; CHECK: loop
741 ; CHECK: i32.atomic.rmw8_u.cmpxchg
741 ; CHECK: i32.atomic.rmw8.cmpxchg_u
742742 ; CHECK: i32.extend8_s
743743 define i32 @nand_sext_i8_i32(i8* %p, i32 %v) {
744744 %t = trunc i32 %v to i8
750750 ; CHECK-LABEL: nand_sext_i16_i32:
751751 ; CHECK-NEXT: .functype nand_sext_i16_i32 (i32, i32) -> (i32){{$}}
752752 ; CHECK: loop
753 ; CHECK: i32.atomic.rmw16_u.cmpxchg
753 ; CHECK: i32.atomic.rmw16.cmpxchg_u
754754 ; CHECK: i32.extend16_s
755755 define i32 @nand_sext_i16_i32(i16* %p, i32 %v) {
756756 %t = trunc i32 %v to i16
759759 ret i32 %e
760760 }
761761
762 ; FIXME Currently this cannot make use of i64.atomic.rmw8_u.cmpxchg
762 ; FIXME Currently this cannot make use of i64.atomic.rmw8.cmpxchg_u
763763 ; CHECK-LABEL: nand_sext_i8_i64:
764764 ; CHECK-NEXT: .functype nand_sext_i8_i64 (i32, i64) -> (i64){{$}}
765765 ; CHECK: loop
766 ; CHECK: i32.atomic.rmw8_u.cmpxchg
767 ; CHECK: i64.extend_u/i32
766 ; CHECK: i32.atomic.rmw8.cmpxchg_u
767 ; CHECK: i64.extend_i32_u
768768 ; CHECK: i64.extend8_s
769769 define i64 @nand_sext_i8_i64(i8* %p, i64 %v) {
770770 %t = trunc i64 %v to i8
773773 ret i64 %e
774774 }
775775
776 ; FIXME Currently this cannot make use of i64.atomic.rmw16_u.cmpxchg
776 ; FIXME Currently this cannot make use of i64.atomic.rmw16.cmpxchg_u
777777 ; CHECK-LABEL: nand_sext_i16_i64:
778778 ; CHECK-NEXT: .functype nand_sext_i16_i64 (i32, i64) -> (i64){{$}}
779779 ; CHECK: loop
780 ; CHECK: i32.atomic.rmw16_u.cmpxchg
781 ; CHECK: i64.extend_u/i32
780 ; CHECK: i32.atomic.rmw16.cmpxchg_u
781 ; CHECK: i64.extend_i32_u
782782 ; CHECK: i64.extend16_s
783783 define i64 @nand_sext_i16_i64(i16* %p, i64 %v) {
784784 %t = trunc i64 %v to i16
787787 ret i64 %e
788788 }
789789
790 ; 32->64 sext rmw gets selected as i32.atomic.rmw.nand, i64_extend_s/i32
790 ; 32->64 sext rmw gets selected as i32.atomic.rmw.nand, i64.extend_i32_s
791791 ; CHECK-LABEL: nand_sext_i32_i64:
792792 ; CHECK-NEXT: .functype nand_sext_i32_i64 (i32, i64) -> (i64){{$}}
793793 ; CHECK: loop
794794 ; CHECK: i32.atomic.rmw.cmpxchg
795 ; CHECK: i64.extend_s/i32
795 ; CHECK: i64.extend_i32_s
796796 define i64 @nand_sext_i32_i64(i32* %p, i64 %v) {
797797 %t = trunc i64 %v to i32
798798 %old = atomicrmw nand i32* %p, i32 %t seq_cst
808808
809809 ; CHECK-LABEL: add_zext_i8_i32:
810810 ; CHECK-NEXT: .functype add_zext_i8_i32 (i32, i32) -> (i32){{$}}
811 ; CHECK: i32.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
811 ; CHECK: i32.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
812812 ; CHECK-NEXT: return $pop0{{$}}
813813 define i32 @add_zext_i8_i32(i8* %p, i32 %v) {
814814 %t = trunc i32 %v to i8
819819
820820 ; CHECK-LABEL: add_zext_i16_i32:
821821 ; CHECK-NEXT: .functype add_zext_i16_i32 (i32, i32) -> (i32){{$}}
822 ; CHECK: i32.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
822 ; CHECK: i32.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
823823 ; CHECK-NEXT: return $pop0{{$}}
824824 define i32 @add_zext_i16_i32(i16* %p, i32 %v) {
825825 %t = trunc i32 %v to i16
830830
831831 ; CHECK-LABEL: add_zext_i8_i64:
832832 ; CHECK-NEXT: .functype add_zext_i8_i64 (i32, i64) -> (i64){{$}}
833 ; CHECK: i64.atomic.rmw8_u.add $push0=, 0($0), $1{{$}}
833 ; CHECK: i64.atomic.rmw8.add_u $push0=, 0($0), $1{{$}}
834834 ; CHECK-NEXT: return $pop0{{$}}
835835 define i64 @add_zext_i8_i64(i8* %p, i64 %v) {
836836 %t = trunc i64 %v to i8
841841
842842 ; CHECK-LABEL: add_zext_i16_i64:
843843 ; CHECK-NEXT: .functype add_zext_i16_i64 (i32, i64) -> (i64){{$}}
844 ; CHECK: i64.atomic.rmw16_u.add $push0=, 0($0), $1{{$}}
844 ; CHECK: i64.atomic.rmw16.add_u $push0=, 0($0), $1{{$}}
845845 ; CHECK-NEXT: return $pop0{{$}}
846846 define i64 @add_zext_i16_i64(i16* %p, i64 %v) {
847847 %t = trunc i64 %v to i16
852852
853853 ; CHECK-LABEL: add_zext_i32_i64:
854854 ; CHECK-NEXT: .functype add_zext_i32_i64 (i32, i64) -> (i64){{$}}
855 ; CHECK: i64.atomic.rmw32_u.add $push0=, 0($0), $1{{$}}
855 ; CHECK: i64.atomic.rmw32.add_u $push0=, 0($0), $1{{$}}
856856 ; CHECK-NEXT: return $pop0{{$}}
857857 define i64 @add_zext_i32_i64(i32* %p, i64 %v) {
858858 %t = trunc i64 %v to i32
865865
866866 ; CHECK-LABEL: sub_zext_i8_i32:
867867 ; CHECK-NEXT: .functype sub_zext_i8_i32 (i32, i32) -> (i32){{$}}
868 ; CHECK: i32.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
868 ; CHECK: i32.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
869869 ; CHECK-NEXT: return $pop0{{$}}
870870 define i32 @sub_zext_i8_i32(i8* %p, i32 %v) {
871871 %t = trunc i32 %v to i8
876876
877877 ; CHECK-LABEL: sub_zext_i16_i32:
878878 ; CHECK-NEXT: .functype sub_zext_i16_i32 (i32, i32) -> (i32){{$}}
879 ; CHECK: i32.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
879 ; CHECK: i32.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
880880 ; CHECK-NEXT: return $pop0{{$}}
881881 define i32 @sub_zext_i16_i32(i16* %p, i32 %v) {
882882 %t = trunc i32 %v to i16
887887
888888 ; CHECK-LABEL: sub_zext_i8_i64:
889889 ; CHECK-NEXT: .functype sub_zext_i8_i64 (i32, i64) -> (i64){{$}}
890 ; CHECK: i64.atomic.rmw8_u.sub $push0=, 0($0), $1{{$}}
890 ; CHECK: i64.atomic.rmw8.sub_u $push0=, 0($0), $1{{$}}
891891 ; CHECK-NEXT: return $pop0{{$}}
892892 define i64 @sub_zext_i8_i64(i8* %p, i64 %v) {
893893 %t = trunc i64 %v to i8
898898
899899 ; CHECK-LABEL: sub_zext_i16_i64:
900900 ; CHECK-NEXT: .functype sub_zext_i16_i64 (i32, i64) -> (i64){{$}}
901 ; CHECK: i64.atomic.rmw16_u.sub $push0=, 0($0), $1{{$}}
901 ; CHECK: i64.atomic.rmw16.sub_u $push0=, 0($0), $1{{$}}
902902 ; CHECK-NEXT: return $pop0{{$}}
903903 define i64 @sub_zext_i16_i64(i16* %p, i64 %v) {
904904 %t = trunc i64 %v to i16
909909
910910 ; CHECK-LABEL: sub_zext_i32_i64:
911911 ; CHECK-NEXT: .functype sub_zext_i32_i64 (i32, i64) -> (i64){{$}}
912 ; CHECK: i64.atomic.rmw32_u.sub $push0=, 0($0), $1{{$}}
912 ; CHECK: i64.atomic.rmw32.sub_u $push0=, 0($0), $1{{$}}
913913 ; CHECK-NEXT: return $pop0{{$}}
914914 define i64 @sub_zext_i32_i64(i32* %p, i64 %v) {
915915 %t = trunc i64 %v to i32
922922
923923 ; CHECK-LABEL: and_zext_i8_i32:
924924 ; CHECK-NEXT: .functype and_zext_i8_i32 (i32, i32) -> (i32){{$}}
925 ; CHECK: i32.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
925 ; CHECK: i32.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
926926 ; CHECK-NEXT: return $pop0{{$}}
927927 define i32 @and_zext_i8_i32(i8* %p, i32 %v) {
928928 %t = trunc i32 %v to i8
933933
934934 ; CHECK-LABEL: and_zext_i16_i32:
935935 ; CHECK-NEXT: .functype and_zext_i16_i32 (i32, i32) -> (i32){{$}}
936 ; CHECK: i32.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
936 ; CHECK: i32.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
937937 ; CHECK-NEXT: return $pop0{{$}}
938938 define i32 @and_zext_i16_i32(i16* %p, i32 %v) {
939939 %t = trunc i32 %v to i16
944944
945945 ; CHECK-LABEL: and_zext_i8_i64:
946946 ; CHECK-NEXT: .functype and_zext_i8_i64 (i32, i64) -> (i64){{$}}
947 ; CHECK: i64.atomic.rmw8_u.and $push0=, 0($0), $1{{$}}
947 ; CHECK: i64.atomic.rmw8.and_u $push0=, 0($0), $1{{$}}
948948 ; CHECK-NEXT: return $pop0{{$}}
949949 define i64 @and_zext_i8_i64(i8* %p, i64 %v) {
950950 %t = trunc i64 %v to i8
955955
956956 ; CHECK-LABEL: and_zext_i16_i64:
957957 ; CHECK-NEXT: .functype and_zext_i16_i64 (i32, i64) -> (i64){{$}}
958 ; CHECK: i64.atomic.rmw16_u.and $push0=, 0($0), $1{{$}}
958 ; CHECK: i64.atomic.rmw16.and_u $push0=, 0($0), $1{{$}}
959959 ; CHECK-NEXT: return $pop0{{$}}
960960 define i64 @and_zext_i16_i64(i16* %p, i64 %v) {
961961 %t = trunc i64 %v to i16
966966
967967 ; CHECK-LABEL: and_zext_i32_i64:
968968 ; CHECK-NEXT: .functype and_zext_i32_i64 (i32, i64) -> (i64){{$}}
969 ; CHECK: i64.atomic.rmw32_u.and $push0=, 0($0), $1{{$}}
969 ; CHECK: i64.atomic.rmw32.and_u $push0=, 0($0), $1{{$}}
970970 ; CHECK-NEXT: return $pop0{{$}}
971971 define i64 @and_zext_i32_i64(i32* %p, i64 %v) {
972972 %t = trunc i64 %v to i32
979979
980980 ; CHECK-LABEL: or_zext_i8_i32:
981981 ; CHECK-NEXT: .functype or_zext_i8_i32 (i32, i32) -> (i32){{$}}
982 ; CHECK: i32.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
982 ; CHECK: i32.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
983983 ; CHECK-NEXT: return $pop0{{$}}
984984 define i32 @or_zext_i8_i32(i8* %p, i32 %v) {
985985 %t = trunc i32 %v to i8
990990
991991 ; CHECK-LABEL: or_zext_i16_i32:
992992 ; CHECK-NEXT: .functype or_zext_i16_i32 (i32, i32) -> (i32){{$}}
993 ; CHECK: i32.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
993 ; CHECK: i32.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
994994 ; CHECK-NEXT: return $pop0{{$}}
995995 define i32 @or_zext_i16_i32(i16* %p, i32 %v) {
996996 %t = trunc i32 %v to i16
10011001
10021002 ; CHECK-LABEL: or_zext_i8_i64:
10031003 ; CHECK-NEXT: .functype or_zext_i8_i64 (i32, i64) -> (i64){{$}}
1004 ; CHECK: i64.atomic.rmw8_u.or $push0=, 0($0), $1{{$}}
1004 ; CHECK: i64.atomic.rmw8.or_u $push0=, 0($0), $1{{$}}
10051005 ; CHECK-NEXT: return $pop0{{$}}
10061006 define i64 @or_zext_i8_i64(i8* %p, i64 %v) {
10071007 %t = trunc i64 %v to i8
10121012
10131013 ; CHECK-LABEL: or_zext_i16_i64:
10141014 ; CHECK-NEXT: .functype or_zext_i16_i64 (i32, i64) -> (i64){{$}}
1015 ; CHECK: i64.atomic.rmw16_u.or $push0=, 0($0), $1{{$}}
1015 ; CHECK: i64.atomic.rmw16.or_u $push0=, 0($0), $1{{$}}
10161016 ; CHECK-NEXT: return $pop0{{$}}
10171017 define i64 @or_zext_i16_i64(i16* %p, i64 %v) {
10181018 %t = trunc i64 %v to i16
10231023
10241024 ; CHECK-LABEL: or_zext_i32_i64:
10251025 ; CHECK-NEXT: .functype or_zext_i32_i64 (i32, i64) -> (i64){{$}}
1026 ; CHECK: i64.atomic.rmw32_u.or $push0=, 0($0), $1{{$}}
1026 ; CHECK: i64.atomic.rmw32.or_u $push0=, 0($0), $1{{$}}
10271027 ; CHECK-NEXT: return $pop0{{$}}
10281028 define i64 @or_zext_i32_i64(i32* %p, i64 %v) {
10291029 %t = trunc i64 %v to i32
10361036
10371037 ; CHECK-LABEL: xor_zext_i8_i32:
10381038 ; CHECK-NEXT: .functype xor_zext_i8_i32 (i32, i32) -> (i32){{$}}
1039 ; CHECK: i32.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
1039 ; CHECK: i32.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
10401040 ; CHECK-NEXT: return $pop0{{$}}
10411041 define i32 @xor_zext_i8_i32(i8* %p, i32 %v) {
10421042 %t = trunc i32 %v to i8
10471047
10481048 ; CHECK-LABEL: xor_zext_i16_i32:
10491049 ; CHECK-NEXT: .functype xor_zext_i16_i32 (i32, i32) -> (i32){{$}}
1050 ; CHECK: i32.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
1050 ; CHECK: i32.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
10511051 ; CHECK-NEXT: return $pop0{{$}}
10521052 define i32 @xor_zext_i16_i32(i16* %p, i32 %v) {
10531053 %t = trunc i32 %v to i16
10581058
10591059 ; CHECK-LABEL: xor_zext_i8_i64:
10601060 ; CHECK-NEXT: .functype xor_zext_i8_i64 (i32, i64) -> (i64){{$}}
1061 ; CHECK: i64.atomic.rmw8_u.xor $push0=, 0($0), $1{{$}}
1061 ; CHECK: i64.atomic.rmw8.xor_u $push0=, 0($0), $1{{$}}
10621062 ; CHECK-NEXT: return $pop0{{$}}
10631063 define i64 @xor_zext_i8_i64(i8* %p, i64 %v) {
10641064 %t = trunc i64 %v to i8
10691069
10701070 ; CHECK-LABEL: xor_zext_i16_i64:
10711071 ; CHECK-NEXT: .functype xor_zext_i16_i64 (i32, i64) -> (i64){{$}}
1072 ; CHECK: i64.atomic.rmw16_u.xor $push0=, 0($0), $1{{$}}
1072 ; CHECK: i64.atomic.rmw16.xor_u $push0=, 0($0), $1{{$}}
10731073 ; CHECK-NEXT: return $pop0{{$}}
10741074 define i64 @xor_zext_i16_i64(i16* %p, i64 %v) {
10751075 %t = trunc i64 %v to i16
10801080
10811081 ; CHECK-LABEL: xor_zext_i32_i64:
10821082 ; CHECK-NEXT: .functype xor_zext_i32_i64 (i32, i64) -> (i64){{$}}
1083 ; CHECK: i64.atomic.rmw32_u.xor $push0=, 0($0), $1{{$}}
1083 ; CHECK: i64.atomic.rmw32.xor_u $push0=, 0($0), $1{{$}}
10841084 ; CHECK-NEXT: return $pop0{{$}}
10851085 define i64 @xor_zext_i32_i64(i32* %p, i64 %v) {
10861086 %t = trunc i64 %v to i32
10931093
10941094 ; CHECK-LABEL: xchg_zext_i8_i32:
10951095 ; CHECK-NEXT: .functype xchg_zext_i8_i32 (i32, i32) -> (i32){{$}}
1096 ; CHECK: i32.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
1096 ; CHECK: i32.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
10971097 ; CHECK-NEXT: return $pop0{{$}}
10981098 define i32 @xchg_zext_i8_i32(i8* %p, i32 %v) {
10991099 %t = trunc i32 %v to i8
11041104
11051105 ; CHECK-LABEL: xchg_zext_i16_i32:
11061106 ; CHECK-NEXT: .functype xchg_zext_i16_i32 (i32, i32) -> (i32){{$}}
1107 ; CHECK: i32.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
1107 ; CHECK: i32.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
11081108 ; CHECK-NEXT: return $pop0{{$}}
11091109 define i32 @xchg_zext_i16_i32(i16* %p, i32 %v) {
11101110 %t = trunc i32 %v to i16
11151115
11161116 ; CHECK-LABEL: xchg_zext_i8_i64:
11171117 ; CHECK-NEXT: .functype xchg_zext_i8_i64 (i32, i64) -> (i64){{$}}
1118 ; CHECK: i64.atomic.rmw8_u.xchg $push0=, 0($0), $1{{$}}
1118 ; CHECK: i64.atomic.rmw8.xchg_u $push0=, 0($0), $1{{$}}
11191119 ; CHECK-NEXT: return $pop0{{$}}
11201120 define i64 @xchg_zext_i8_i64(i8* %p, i64 %v) {
11211121 %t = trunc i64 %v to i8
11261126
11271127 ; CHECK-LABEL: xchg_zext_i16_i64:
11281128 ; CHECK-NEXT: .functype xchg_zext_i16_i64 (i32, i64) -> (i64){{$}}
1129 ; CHECK: i64.atomic.rmw16_u.xchg $push0=, 0($0), $1{{$}}
1129 ; CHECK: i64.atomic.rmw16.xchg_u $push0=, 0($0), $1{{$}}
11301130 ; CHECK-NEXT: return $pop0{{$}}
11311131 define i64 @xchg_zext_i16_i64(i16* %p, i64 %v) {
11321132 %t = trunc i64 %v to i16
11371137
11381138 ; CHECK-LABEL: xchg_zext_i32_i64:
11391139 ; CHECK-NEXT: .functype xchg_zext_i32_i64 (i32, i64) -> (i64){{$}}
1140 ; CHECK: i64.atomic.rmw32_u.xchg $push0=, 0($0), $1{{$}}
1140 ; CHECK: i64.atomic.rmw32.xchg_u $push0=, 0($0), $1{{$}}
11411141 ; CHECK-NEXT: return $pop0{{$}}
11421142 define i64 @xchg_zext_i32_i64(i32* %p, i64 %v) {
11431143 %t = trunc i64 %v to i32
11501150
11511151 ; CHECK-LABEL: cmpxchg_zext_i8_i32:
11521152 ; CHECK-NEXT: .functype cmpxchg_zext_i8_i32 (i32, i32, i32) -> (i32){{$}}
1153 ; CHECK: i32.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1153 ; CHECK: i32.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
11541154 ; CHECK-NEXT: return $pop0{{$}}
11551155 define i32 @cmpxchg_zext_i8_i32(i8* %p, i32 %exp, i32 %new) {
11561156 %exp_t = trunc i32 %exp to i8
11631163
11641164 ; CHECK-LABEL: cmpxchg_zext_i16_i32:
11651165 ; CHECK-NEXT: .functype cmpxchg_zext_i16_i32 (i32, i32, i32) -> (i32){{$}}
1166 ; CHECK: i32.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1166 ; CHECK: i32.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
11671167 ; CHECK-NEXT: return $pop0{{$}}
11681168 define i32 @cmpxchg_zext_i16_i32(i16* %p, i32 %exp, i32 %new) {
11691169 %exp_t = trunc i32 %exp to i16
11761176
11771177 ; CHECK-LABEL: cmpxchg_zext_i8_i64:
11781178 ; CHECK-NEXT: .functype cmpxchg_zext_i8_i64 (i32, i64, i64) -> (i64){{$}}
1179 ; CHECK: i64.atomic.rmw8_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1179 ; CHECK: i64.atomic.rmw8.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
11801180 ; CHECK-NEXT: return $pop0{{$}}
11811181 define i64 @cmpxchg_zext_i8_i64(i8* %p, i64 %exp, i64 %new) {
11821182 %exp_t = trunc i64 %exp to i8
11891189
11901190 ; CHECK-LABEL: cmpxchg_zext_i16_i64:
11911191 ; CHECK-NEXT: .functype cmpxchg_zext_i16_i64 (i32, i64, i64) -> (i64){{$}}
1192 ; CHECK: i64.atomic.rmw16_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1192 ; CHECK: i64.atomic.rmw16.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
11931193 ; CHECK-NEXT: return $pop0{{$}}
11941194 define i64 @cmpxchg_zext_i16_i64(i16* %p, i64 %exp, i64 %new) {
11951195 %exp_t = trunc i64 %exp to i16
12021202
12031203 ; CHECK-LABEL: cmpxchg_zext_i32_i64:
12041204 ; CHECK-NEXT: .functype cmpxchg_zext_i32_i64 (i32, i64, i64) -> (i64){{$}}
1205 ; CHECK: i64.atomic.rmw32_u.cmpxchg $push0=, 0($0), $1, $2{{$}}
1205 ; CHECK: i64.atomic.rmw32.cmpxchg_u $push0=, 0($0), $1, $2{{$}}
12061206 ; CHECK-NEXT: return $pop0{{$}}
12071207 define i64 @cmpxchg_zext_i32_i64(i32* %p, i64 %exp, i64 %new) {
12081208 %exp_t = trunc i64 %exp to i32
12211221 ; CHECK-LABEL: nand_zext_i8_i32:
12221222 ; CHECK-NEXT: .functype nand_zext_i8_i32 (i32, i32) -> (i32){{$}}
12231223 ; CHECK: loop
1224 ; CHECK: i32.atomic.rmw8_u.cmpxchg
1224 ; CHECK: i32.atomic.rmw8.cmpxchg_u
12251225 define i32 @nand_zext_i8_i32(i8* %p, i32 %v) {
12261226 %t = trunc i32 %v to i8
12271227 %old = atomicrmw nand i8* %p, i8 %t seq_cst
12321232 ; CHECK-LABEL: nand_zext_i16_i32:
12331233 ; CHECK-NEXT: .functype nand_zext_i16_i32 (i32, i32) -> (i32){{$}}
12341234 ; CHECK: loop
1235 ; CHECK: i32.atomic.rmw16_u.cmpxchg
1235 ; CHECK: i32.atomic.rmw16.cmpxchg_u
12361236 define i32 @nand_zext_i16_i32(i16* %p, i32 %v) {
12371237 %t = trunc i32 %v to i16
12381238 %old = atomicrmw nand i16* %p, i16 %t seq_cst
12401240 ret i32 %e
12411241 }
12421242
1243 ; FIXME Currently this cannot make use of i64.atomic.rmw8_u.cmpxchg
1243 ; FIXME Currently this cannot make use of i64.atomic.rmw8.cmpxchg_u
12441244 ; CHECK-LABEL: nand_zext_i8_i64:
12451245 ; CHECK-NEXT: .functype nand_zext_i8_i64 (i32, i64) -> (i64){{$}}
12461246 ; CHECK: loop
1247 ; CHECK: i32.atomic.rmw8_u.cmpxchg
1248 ; CHECK: i64.extend_u/i32
1247 ; CHECK: i32.atomic.rmw8.cmpxchg_u
1248 ; CHECK: i64.extend_i32_u
12491249 define i64 @nand_zext_i8_i64(i8* %p, i64 %v) {
12501250 %t = trunc i64 %v to i8
12511251 %old = atomicrmw nand i8* %p, i8 %t seq_cst
12531253 ret i64 %e
12541254 }
12551255
1256 ; FIXME Currently this cannot make use of i64.atomic.rmw16_u.cmpxchg
1256 ; FIXME Currently this cannot make use of i64.atomic.rmw16.cmpxchg_u
12571257 ; CHECK-LABEL: nand_zext_i16_i64:
12581258 ; CHECK-NEXT: .functype nand_zext_i16_i64 (i32, i64) -> (i64){{$}}
12591259 ; CHECK: loop
1260 ; CHECK: i32.atomic.rmw16_u.cmpxchg
1261 ; CHECK: i64.extend_u/i32
1260 ; CHECK: i32.atomic.rmw16.cmpxchg_u
1261 ; CHECK: i64.extend_i32_u
12621262 define i64 @nand_zext_i16_i64(i16* %p, i64 %v) {
12631263 %t = trunc i64 %v to i16
12641264 %old = atomicrmw nand i16* %p, i16 %t seq_cst
12661266 ret i64 %e
12671267 }
12681268
1269 ; FIXME Currently this cannot make use of i64.atomic.rmw32_u.cmpxchg
1269 ; FIXME Currently this cannot make use of i64.atomic.rmw32.cmpxchg_u
12701270 ; CHECK-LABEL: nand_zext_i32_i64:
12711271 ; CHECK-NEXT: .functype nand_zext_i32_i64 (i32, i64) -> (i64){{$}}
12721272 ; CHECK: loop
12731273 ; CHECK: i32.atomic.rmw.cmpxchg
1274 ; CHECK: i64.extend_u/i32
1274 ; CHECK: i64.extend_i32_u
12751275 define i64 @nand_zext_i32_i64(i32* %p, i64 %v) {
12761276 %t = trunc i64 %v to i32
12771277 %old = atomicrmw nand i32* %p, i32 %t seq_cst
2020 define void @byval_arg(%SmallStruct* %ptr) {
2121 ; CHECK: .functype byval_arg (i32) -> ()
2222 ; Subtract 16 from SP (SP is 16-byte aligned)
23 ; CHECK-NEXT: get_global $push[[L2:.+]]=, __stack_pointer@GLOBAL
23 ; CHECK-NEXT: global.get $push[[L2:.+]]=, __stack_pointer@GLOBAL
2424 ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
2525 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
2626 ; Ensure SP is stored back before the call
27 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
28 ; CHECK-NEXT: set_global __stack_pointer@GLOBAL, $pop[[L10]]{{$}}
27 ; CHECK-NEXT: local.tee $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
28 ; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop[[L10]]{{$}}
2929 ; Copy the SmallStruct argument to the stack (SP+12, original SP-4)
3030 ; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
3131 ; CHECK-NEXT: i32.store 12($[[SP]]), $pop[[L0]]
3737 ; Restore the stack
3838 ; CHECK-NEXT: i32.const $push[[L6:.+]]=, 16
3939 ; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L6]]
40 ; CHECK-NEXT: set_global __stack_pointer@GLOBAL, $pop[[L8]]
40 ; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop[[L8]]
4141 ; CHECK-NEXT: return
4242 ret void
4343 }
4848 ; Don't check the entire SP sequence, just enough to get the alignment.
4949 ; CHECK: i32.const $push[[L1:.+]]=, 16
5050 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, {{.+}}, $pop[[L1]]
51 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
52 ; CHECK-NEXT: set_global __stack_pointer@GLOBAL, $pop[[L10]]{{$}}
51 ; CHECK-NEXT: local.tee $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
52 ; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop[[L10]]{{$}}
5353 ; Copy the SmallStruct argument to the stack (SP+8, original SP-8)
5454 ; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0){{$}}
5555 ; CHECK-NEXT: i32.store 8($[[SP]]), $pop[[L0]]{{$}}
6767 ; Subtract 16 from SP (SP is 16-byte aligned)
6868 ; CHECK: i32.const $push[[L1:.+]]=, 16
6969 ; CHECK-NEXT: i32.sub $push[[L14:.+]]=, {{.+}}, $pop[[L1]]
70 ; CHECK-NEXT: tee_local $push[[L13:.+]]=, $[[SP:.+]]=, $pop[[L14]]
71 ; CHECK-NEXT: set_global __stack_pointer@GLOBAL, $pop[[L13]]
70 ; CHECK-NEXT: local.tee $push[[L13:.+]]=, $[[SP:.+]]=, $pop[[L14]]
71 ; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop[[L13]]
7272 ; Copy the AlignedStruct argument to the stack (SP+0, original SP-16)
7373 ; Just check the last load/store pair of the memcpy
7474 ; CHECK: i64.load $push[[L4:.+]]=, 0($0)
106106
107107 ; Call memcpy for "big" byvals.
108108 ; CHECK-LABEL: big_byval:
109 ; CHECK: get_global $push[[L2:.+]]=, __stack_pointer@GLOBAL{{$}}
109 ; CHECK: global.get $push[[L2:.+]]=, __stack_pointer@GLOBAL{{$}}
110110 ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 131072
111111 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
112 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
113 ; CHECK-NEXT: set_global __stack_pointer@GLOBAL, $pop[[L10]]{{$}}
112 ; CHECK-NEXT: local.tee $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
113 ; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop[[L10]]{{$}}
114114 ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 131072
115115 ; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $[[SP]], ${{.+}}, $pop{{.+}}
116 ; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
116 ; CHECK-NEXT: local.tee $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
117117 ; CHECK-NEXT: call big_byval_callee@FUNCTION,
118118 %big = type [131072 x i8]
119119 declare void @big_byval_callee(%big* byval align 1)
7070
7171 ; CHECK-LABEL: call_i32_unary:
7272 ; CHECK-NEXT: .functype call_i32_unary (i32) -> (i32){{$}}
73 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
73 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
7474 ; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_unary@FUNCTION, $pop[[L0]]{{$}}
7575 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
7676 define i32 @call_i32_unary(i32 %a) {
8080
8181 ; CHECK-LABEL: call_i32_binary:
8282 ; CHECK-NEXT: .functype call_i32_binary (i32, i32) -> (i32){{$}}
83 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
84 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
83 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
84 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
8585 ; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_binary@FUNCTION, $pop[[L0]], $pop[[L1]]{{$}}
8686 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
8787 define i32 @call_i32_binary(i32 %a, i32 %b) {
9191
9292 ; CHECK-LABEL: call_indirect_void:
9393 ; CHECK-NEXT: .functype call_indirect_void (i32) -> (){{$}}
94 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
94 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
9595 ; CHECK-NEXT: {{^}} call_indirect $pop[[L0]]{{$}}
9696 ; CHECK-NEXT: return{{$}}
9797 define void @call_indirect_void(void ()* %callee) {
101101
102102 ; CHECK-LABEL: call_indirect_i32:
103103 ; CHECK-NEXT: .functype call_indirect_i32 (i32) -> (i32){{$}}
104 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
104 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
105105 ; CHECK-NEXT: {{^}} i32.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
106106 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
107107 define i32 @call_indirect_i32(i32 ()* %callee) {
111111
112112 ; CHECK-LABEL: call_indirect_i64:
113113 ; CHECK-NEXT: .functype call_indirect_i64 (i32) -> (i64){{$}}
114 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
114 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
115115 ; CHECK-NEXT: {{^}} i64.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
116116 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
117117 define i64 @call_indirect_i64(i64 ()* %callee) {
121121
122122 ; CHECK-LABEL: call_indirect_float:
123123 ; CHECK-NEXT: .functype call_indirect_float (i32) -> (f32){{$}}
124 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
124 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
125125 ; CHECK-NEXT: {{^}} f32.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
126126 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
127127 define float @call_indirect_float(float ()* %callee) {
131131
132132 ; CHECK-LABEL: call_indirect_double:
133133 ; CHECK-NEXT: .functype call_indirect_double (i32) -> (f64){{$}}
134 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
134 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
135135 ; CHECK-NEXT: {{^}} f64.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
136136 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
137137 define double @call_indirect_double(double ()* %callee) {
141141
142142 ; CHECK-LABEL: call_indirect_v128:
143143 ; CHECK-NEXT: .functype call_indirect_v128 (i32) -> (v128){{$}}
144 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
144 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
145145 ; CHECK-NEXT: {{^}} v128.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}}
146146 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
147147 define <16 x i8> @call_indirect_v128(<16 x i8> ()* %callee) {
151151
152152 ; CHECK-LABEL: call_indirect_arg:
153153 ; CHECK-NEXT: .functype call_indirect_arg (i32, i32) -> (){{$}}
154 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 1{{$}}
155 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}}
154 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 1{{$}}
155 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
156156 ; CHECK-NEXT: {{^}} call_indirect $pop[[L0]], $pop[[L1]]{{$}}
157157 ; CHECK-NEXT: return{{$}}
158158 define void @call_indirect_arg(void (i32)* %callee, i32 %arg) {
162162
163163 ; CHECK-LABEL: call_indirect_arg_2:
164164 ; CHECK-NEXT: .functype call_indirect_arg_2 (i32, i32, i32) -> (){{$}}
165 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 1{{$}}
166 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 2{{$}}
167 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}}
165 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 1{{$}}
166 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 2{{$}}
167 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
168168 ; CHECK-NEXT: {{^}} i32.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]], $pop[[L2]]{{$}}
169169 ; CHECK-NEXT: drop $pop[[NUM]]{{$}}
170170 ; CHECK-NEXT: return{{$}}
66 ; CHECK: body:
77 ; CHECK: BLOCK
88 ; <-- Stackified expression starts
9 ; CHECK-NEXT: GET_LOCAL_I64
9 ; CHECK-NEXT: LOCAL_GET_I64
1010 ; CHECK-NEXT: I32_WRAP_I64
1111 ; CHECK-NEXT: DBG_VALUE
1212 ; <-- BLOCK should NOT be placed here!
9797 successors: %bb.2, %bb.7
9898
9999 %30:i32 = CATCH_I32 0, implicit-def dead $arguments
100 SET_LOCAL_I32 0, %30:i32, implicit-def $arguments
100 LOCAL_SET_I32 0, %30:i32, implicit-def $arguments
101101 %16:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
102102 %27:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
103103 STORE_I32 2, @__wasm_lpad_context + 4, %16:i32, %27:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack :: (store 4 into `i8** getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 1)`)
104104 %26:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
105105 %25:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
106106 STORE_I32 2, @__wasm_lpad_context, %26:i32, %25:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack :: (store 4 into `i32* getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 0)`)
107 %32:i32 = GET_LOCAL_I32 0, implicit-def $arguments
107 %32:i32 = LOCAL_GET_I32 0, implicit-def $arguments
108108 %31:i32 = CALL_I32 @_Unwind_CallPersonality, %32:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
109109 DROP_I32 killed %31:i32, implicit-def $arguments
110110 %24:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
117117 ; predecessors: %bb.1
118118 successors: %bb.8, %bb.3, %bb.6
119119
120 %34:i32 = GET_LOCAL_I32 0, implicit-def $arguments
120 %34:i32 = LOCAL_GET_I32 0, implicit-def $arguments
121121 %33:i32 = CALL_I32 @__cxa_begin_catch, %34:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
122122 DROP_I32 killed %33:i32, implicit-def $arguments
123123 CALL_VOID @may_throw, implicit-def dead $arguments, implicit $sp32, implicit $sp64
133133 successors: %bb.4, %bb.5
134134
135135 %35:i32 = CATCH_I32 0, implicit-def dead $arguments
136 SET_LOCAL_I32 0, %35:i32, implicit-def $arguments
136 LOCAL_SET_I32 0, %35:i32, implicit-def $arguments
137137 %21:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
138138 %20:i32 = CONST_I32 1, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
139139 STORE_I32 2, @__wasm_lpad_context, %21:i32, %20:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack :: (store 4 into `i32* getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 0)`)
140 %37:i32 = GET_LOCAL_I32 0, implicit-def $arguments
140 %37:i32 = LOCAL_GET_I32 0, implicit-def $arguments
141141 %36:i32 = CALL_I32 @_Unwind_CallPersonality, %37:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
142142 DROP_I32 killed %36:i32, implicit-def $arguments
143143 %29:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
150150 ; predecessors: %bb.3
151151 successors: %bb.8
152152
153 %39:i32 = GET_LOCAL_I32 0, implicit-def $arguments
153 %39:i32 = LOCAL_GET_I32 0, implicit-def $arguments
154154 %38:i32 = CALL_I32 @__cxa_begin_catch, %39:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
155155 DROP_I32 killed %38:i32, implicit-def $arguments
156156 CALL_VOID @__cxa_end_catch, implicit-def dead $arguments, implicit $sp32, implicit $sp64
211211 successors: %bb.1, %bb.4
212212
213213 %18:i32 = CONST_I32 0, implicit-def dead $arguments
214 SET_LOCAL_I32 1, %18:i32, implicit-def $arguments
214 LOCAL_SET_I32 1, %18:i32, implicit-def $arguments
215215 %14:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
216 %19:i32 = GET_LOCAL_I32 0, implicit-def $arguments
216 %19:i32 = LOCAL_GET_I32 0, implicit-def $arguments
217217 %9:i32 = GE_S_I32 %14:i32, %19:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
218218 BR_IF %bb.4, %9:i32, implicit-def $arguments
219219
242242 ; predecessors: %bb.1
243243 successors: %bb.1, %bb.4
244244
245 %20:i32 = GET_LOCAL_I32 1, implicit-def $arguments
245 %20:i32 = LOCAL_GET_I32 1, implicit-def $arguments
246246 %17:i32 = CONST_I32 1, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
247247 %16:i32 = ADD_I32 %20:i32, %17:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
248 %15:i32 = TEE_LOCAL_I32 1, %16:i32, implicit-def $arguments
249 %21:i32 = GET_LOCAL_I32 0, implicit-def $arguments
248 %15:i32 = LOCAL_TEE_I32 1, %16:i32, implicit-def $arguments
249 %21:i32 = LOCAL_GET_I32 0, implicit-def $arguments
250250 %10:i32 = GE_S_I32 %15:i32, %21:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
251251 BR_UNLESS %bb.1, %10:i32, implicit-def $arguments
252252 ; CHECK-LABEL: bb.3:
288288 %18:i32 = CALL_I32 @__cxa_begin_catch, %9:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64, implicit-def $value_stack, implicit $value_stack
289289 DROP_I32 killed %18:i32, implicit-def $arguments
290290 %19:i32 = CONST_I32 0, implicit-def dead $arguments
291 SET_LOCAL_I32 1, %19:i32, implicit-def $arguments
291 LOCAL_SET_I32 1, %19:i32, implicit-def $arguments
292292 %14:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
293 %20:i32 = GET_LOCAL_I32 0, implicit-def $arguments
293 %20:i32 = LOCAL_GET_I32 0, implicit-def $arguments
294294 %10:i32 = GE_S_I32 %14:i32, %20:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
295295 BR_IF %bb.3, %10:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
296296
299299 successors: %bb.2, %bb.3
300300
301301 CALL_VOID @dont_throw, implicit-def dead $arguments, implicit $sp32, implicit $sp64
302 %21:i32 = GET_LOCAL_I32 1, implicit-def $arguments
302 %21:i32 = LOCAL_GET_I32 1, implicit-def $arguments
303303 %17:i32 = CONST_I32 1, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
304304 %16:i32 = ADD_I32 %21:i32, %17:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
305 %15:i32 = TEE_LOCAL_I32 1, %16:i32, implicit-def $arguments
306 %22:i32 = GET_LOCAL_I32 0, implicit-def $arguments
305 %15:i32 = LOCAL_TEE_I32 1, %16:i32, implicit-def $arguments
306 %22:i32 = LOCAL_GET_I32 0, implicit-def $arguments
307307 %11:i32 = GE_S_I32 %15:i32, %22:i32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack
308308 BR_UNLESS %bb.2, %11:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
309309
77
88 ; CHECK-LABEL: ord_f32:
99 ; CHECK-NEXT: .functype ord_f32 (f32, f32) -> (i32){{$}}
10 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}}
10 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
1212 ; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
13 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 1{{$}}
14 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 1{{$}}
13 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
14 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
1515 ; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
1616 ; CHECK-NEXT: i32.and $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
1717 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
2323
2424 ; CHECK-LABEL: uno_f32:
2525 ; CHECK-NEXT: .functype uno_f32 (f32, f32) -> (i32){{$}}
26 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
27 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}}
26 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
27 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
2828 ; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
29 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 1{{$}}
30 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 1{{$}}
29 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
30 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
3131 ; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
3232 ; CHECK-NEXT: i32.or $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
3333 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
3939
4040 ; CHECK-LABEL: oeq_f32:
4141 ; CHECK-NEXT: .functype oeq_f32 (f32, f32) -> (i32){{$}}
42 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
43 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
42 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
43 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
4444 ; CHECK-NEXT: f32.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
4545 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
4646 define i32 @oeq_f32(float %x, float %y) {
9999
100100 ; CHECK-LABEL: ueq_f32:
101101 ; CHECK-NEXT: .functype ueq_f32 (f32, f32) -> (i32){{$}}
102 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
103 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
102 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
103 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
104104 ; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
105 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}}
106 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 0{{$}}
105 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
106 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}}
107107 ; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
108 ; CHECK-NEXT: get_local $push[[L4:[0-9]+]]=, 1{{$}}
109 ; CHECK-NEXT: get_local $push[[L5:[0-9]+]]=, 1{{$}}
108 ; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}}
109 ; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}}
110110 ; CHECK-NEXT: f32.ne $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
111111 ; CHECK-NEXT: i32.or $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
112112 ; CHECK-NEXT: i32.or $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}}
119119
120120 ; CHECK-LABEL: one_f32:
121121 ; CHECK-NEXT: .functype one_f32 (f32, f32) -> (i32){{$}}
122 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
123 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
122 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
123 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
124124 ; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
125 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}}
126 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 0{{$}}
125 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
126 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}}
127127 ; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
128 ; CHECK-NEXT: get_local $push[[L4:[0-9]+]]=, 1{{$}}
129 ; CHECK-NEXT: get_local $push[[L5:[0-9]+]]=, 1{{$}}
128 ; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}}
129 ; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}}
130130 ; CHECK-NEXT: f32.eq $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
131131 ; CHECK-NEXT: i32.and $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
132132 ; CHECK-NEXT: i32.and $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}}
139139
140140 ; CHECK-LABEL: ult_f32:
141141 ; CHECK-NEXT: .functype ult_f32 (f32, f32) -> (i32){{$}}
142 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
143 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
142 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
143 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
144144 ; CHECK-NEXT: f32.ge $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
145145 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
146146 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
153153
154154 ; CHECK-LABEL: ule_f32:
155155 ; CHECK-NEXT: .functype ule_f32 (f32, f32) -> (i32){{$}}
156 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
157 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
156 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
157 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
158158 ; CHECK-NEXT: f32.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
159159 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
160160 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
167167
168168 ; CHECK-LABEL: ugt_f32:
169169 ; CHECK-NEXT: .functype ugt_f32 (f32, f32) -> (i32){{$}}
170 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
171 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
170 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
171 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
172172 ; CHECK-NEXT: f32.le $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
173173 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
174174 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
181181
182182 ; CHECK-LABEL: uge_f32:
183183 ; CHECK-NEXT: .functype uge_f32 (f32, f32) -> (i32){{$}}
184 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
185 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
184 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
185 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
186186 ; CHECK-NEXT: f32.lt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
187187 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
188188 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
77
88 ; CHECK-LABEL: ord_f64:
99 ; CHECK-NEXT: .functype ord_f64 (f64, f64) -> (i32){{$}}
10 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}}
10 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
1212 ; CHECK-NEXT: f64.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
13 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 1{{$}}
14 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 1{{$}}
13 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
14 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
1515 ; CHECK-NEXT: f64.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
1616 ; CHECK-NEXT: i32.and $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
1717 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
2323
2424 ; CHECK-LABEL: uno_f64:
2525 ; CHECK-NEXT: .functype uno_f64 (f64, f64) -> (i32){{$}}
26 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
27 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}}
26 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
27 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
2828 ; CHECK-NEXT: f64.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
29 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 1{{$}}
30 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 1{{$}}
29 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
30 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
3131 ; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
3232 ; CHECK-NEXT: i32.or $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
3333 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
3939
4040 ; CHECK-LABEL: oeq_f64:
4141 ; CHECK-NEXT: .functype oeq_f64 (f64, f64) -> (i32){{$}}
42 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
43 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
42 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
43 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
4444 ; CHECK-NEXT: f64.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
4545 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
4646 define i32 @oeq_f64(double %x, double %y) {
9898
9999 ; CHECK-LABEL: ueq_f64:
100100 ; CHECK-NEXT: .functype ueq_f64 (f64, f64) -> (i32){{$}}
101 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
101 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
103103 ; CHECK-NEXT: f64.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
104 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}}
105 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 0{{$}}
104 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
105 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}}
106106 ; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
107 ; CHECK-NEXT: get_local $push[[L4:[0-9]+]]=, 1{{$}}
108 ; CHECK-NEXT: get_local $push[[L5:[0-9]+]]=, 1{{$}}
107 ; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}}
108 ; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}}
109109 ; CHECK-NEXT: f64.ne $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
110110 ; CHECK-NEXT: i32.or $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
111111 ; CHECK-NEXT: i32.or $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}}
118118
119119 ; CHECK-LABEL: one_f64:
120120 ; CHECK-NEXT: .functype one_f64 (f64, f64) -> (i32){{$}}
121 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
122 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
121 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
122 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
123123 ; CHECK-NEXT: f64.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
124 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}}
125 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 0{{$}}
124 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
125 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}}
126126 ; CHECK-NEXT: f64.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
127 ; CHECK-NEXT: get_local $push[[L4:[0-9]+]]=, 1{{$}}
128 ; CHECK-NEXT: get_local $push[[L5:[0-9]+]]=, 1{{$}}
127 ; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}}
128 ; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}}
129129 ; CHECK-NEXT: f64.eq $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
130130 ; CHECK-NEXT: i32.and $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
131131 ; CHECK-NEXT: i32.and $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}}
138138
139139 ; CHECK-LABEL: ult_f64:
140140 ; CHECK-NEXT: .functype ult_f64 (f64, f64) -> (i32){{$}}
141 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
142 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
141 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
142 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
143143 ; CHECK-NEXT: f64.ge $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
144144 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
145145 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
152152
153153 ; CHECK-LABEL: ule_f64:
154154 ; CHECK-NEXT: .functype ule_f64 (f64, f64) -> (i32){{$}}
155 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
156 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
155 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
156 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
157157 ; CHECK-NEXT: f64.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
158158 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
159159 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
166166
167167 ; CHECK-LABEL: ugt_f64:
168168 ; CHECK-NEXT: .functype ugt_f64 (f64, f64) -> (i32){{$}}
169 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
170 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
169 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
170 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
171171 ; CHECK-NEXT: f64.le $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
172172 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
173173 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
180180
181181 ; CHECK-LABEL: uge_f64:
182182 ; CHECK-NEXT: .functype uge_f64 (f64, f64) -> (i32){{$}}
183 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
184 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
183 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
184 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
185185 ; CHECK-NEXT: f64.lt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
186186 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
187187 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
77
88 ; CHECK-LABEL: eq_i32:
99 ; CHECK-NEXT: .functype eq_i32 (i32, i32) -> (i32){{$}}
10 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
10 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
1212 ; CHECK-NEXT: i32.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
1313 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
1414 define i32 @eq_i32(i32 %x, i32 %y) {
77
88 ; CHECK-LABEL: eq_i64:
99 ; CHECK-NEXT: .functype eq_i64 (i64, i64) -> (i32){{$}}
10 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
10 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
1212 ; CHECK-NEXT: i64.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
1313 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
1414 define i32 @eq_i64(i64 %x, i64 %y) {
1616 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
1717 ; CHECK-NEXT: BB
1818 ; CHECK-NEXT: end_block
19 ; CHECK-NEXT: i32.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
19 ; CHECK-NEXT: i32.trunc_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
2020 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
2121 define i32 @i32_trunc_s_f32(float %x) {
2222 %a = fptosi float %x to i32
3636 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
3737 ; CHECK-NEXT: BB
3838 ; CHECK-NEXT: end_block
39 ; CHECK-NEXT: i32.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
39 ; CHECK-NEXT: i32.trunc_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
4040 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
4141 define i32 @i32_trunc_u_f32(float %x) {
4242 %a = fptoui float %x to i32
5454 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
5555 ; CHECK-NEXT: BB
5656 ; CHECK-NEXT: end_block
57 ; CHECK-NEXT: i32.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
57 ; CHECK-NEXT: i32.trunc_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
5858 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
5959 define i32 @i32_trunc_s_f64(double %x) {
6060 %a = fptosi double %x to i32
7474 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
7575 ; CHECK-NEXT: BB
7676 ; CHECK-NEXT: end_block
77 ; CHECK-NEXT: i32.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
77 ; CHECK-NEXT: i32.trunc_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
7878 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
7979 define i32 @i32_trunc_u_f64(double %x) {
8080 %a = fptoui double %x to i32
9292 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
9393 ; CHECK-NEXT: BB
9494 ; CHECK-NEXT: end_block
95 ; CHECK-NEXT: i64.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
95 ; CHECK-NEXT: i64.trunc_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
9696 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
9797 define i64 @i64_trunc_s_f32(float %x) {
9898 %a = fptosi float %x to i64
112112 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
113113 ; CHECK-NEXT: BB
114114 ; CHECK-NEXT: end_block
115 ; CHECK-NEXT: i64.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
115 ; CHECK-NEXT: i64.trunc_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
116116 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
117117 define i64 @i64_trunc_u_f32(float %x) {
118118 %a = fptoui float %x to i64
130130 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
131131 ; CHECK-NEXT: BB
132132 ; CHECK-NEXT: end_block
133 ; CHECK-NEXT: i64.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
133 ; CHECK-NEXT: i64.trunc_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
134134 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
135135 define i64 @i64_trunc_s_f64(double %x) {
136136 %a = fptosi double %x to i64
150150 ; CHECK-NEXT: return $pop[[ALT]]{{$}}
151151 ; CHECK-NEXT: BB
152152 ; CHECK-NEXT: end_block
153 ; CHECK-NEXT: i64.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
153 ; CHECK-NEXT: i64.trunc_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
154154 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
155155 define i64 @i64_trunc_u_f64(double %x) {
156156 %a = fptoui double %x to i64
66
77 ; CHECK-LABEL: i32_wrap_i64:
88 ; CHECK-NEXT: .functype i32_wrap_i64 (i64) -> (i32){{$}}
9 ; CHECK-NEXT: i32.wrap/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
9 ; CHECK-NEXT: i32.wrap_i64 $push[[NUM:[0-9]+]]=, $0{{$}}
1010 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
1111 define i32 @i32_wrap_i64(i64 %x) {
1212 %a = trunc i64 %x to i32
1515
1616 ; CHECK-LABEL: i64_extend_s_i32:
1717 ; CHECK-NEXT: .functype i64_extend_s_i32 (i32) -> (i64){{$}}
18 ; CHECK-NEXT: i64.extend_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
18 ; CHECK-NEXT: i64.extend_i32_s $push[[NUM:[0-9]+]]=, $0{{$}}
1919 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
2020 define i64 @i64_extend_s_i32(i32 %x) {
2121 %a = sext i32 %x to i64
2424
2525 ; CHECK-LABEL: i64_extend_u_i32:
2626 ; CHECK-NEXT: .functype i64_extend_u_i32 (i32) -> (i64){{$}}
27 ; CHECK-NEXT: i64.extend_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
27 ; CHECK-NEXT: i64.extend_i32_u $push[[NUM:[0-9]+]]=, $0{{$}}
2828 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
2929 define i64 @i64_extend_u_i32(i32 %x) {
3030 %a = zext i32 %x to i64
3333
3434 ; CHECK-LABEL: i32_trunc_s_f32:
3535 ; CHECK-NEXT: .functype i32_trunc_s_f32 (f32) -> (i32){{$}}
36 ; CHECK-NEXT: i32.trunc_s:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
36 ; CHECK-NEXT: i32.trunc_sat_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
3737 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
3838 define i32 @i32_trunc_s_f32(float %x) {
3939 %a = fptosi float %x to i32
4242
4343 ; CHECK-LABEL: i32_trunc_sat_s_f32:
4444 ; CHECK-NEXT: .functype i32_trunc_sat_s_f32 (f32) -> (i32){{$}}
45 ; CHECK-NEXT: i32.trunc_s:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
45 ; CHECK-NEXT: i32.trunc_sat_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
4646 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
4747 declare i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float)
4848 define i32 @i32_trunc_sat_s_f32(float %x) {
5252
5353 ; CHECK-LABEL: i32_trunc_u_f32:
5454 ; CHECK-NEXT: .functype i32_trunc_u_f32 (f32) -> (i32){{$}}
55 ; CHECK-NEXT: i32.trunc_u:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
55 ; CHECK-NEXT: i32.trunc_sat_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
5656 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
5757 define i32 @i32_trunc_u_f32(float %x) {
5858 %a = fptoui float %x to i32
6161
6262 ; CHECK-LABEL: i32_trunc_sat_u_f32:
6363 ; CHECK-NEXT: .functype i32_trunc_sat_u_f32 (f32) -> (i32){{$}}
64 ; CHECK-NEXT: i32.trunc_u:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
64 ; CHECK-NEXT: i32.trunc_sat_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
6565 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
6666 declare i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float)
6767 define i32 @i32_trunc_sat_u_f32(float %x) {
7171
7272 ; CHECK-LABEL: i32_trunc_s_f64:
7373 ; CHECK-NEXT: .functype i32_trunc_s_f64 (f64) -> (i32){{$}}
74 ; CHECK-NEXT: i32.trunc_s:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
74 ; CHECK-NEXT: i32.trunc_sat_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
7575 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
7676 define i32 @i32_trunc_s_f64(double %x) {
7777 %a = fptosi double %x to i32
8080
8181 ; CHECK-LABEL: i32_trunc_sat_s_f64:
8282 ; CHECK-NEXT: .functype i32_trunc_sat_s_f64 (f64) -> (i32){{$}}
83 ; CHECK-NEXT: i32.trunc_s:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
83 ; CHECK-NEXT: i32.trunc_sat_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
8484 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
8585 declare i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double)
8686 define i32 @i32_trunc_sat_s_f64(double %x) {
9090
9191 ; CHECK-LABEL: i32_trunc_u_f64:
9292 ; CHECK-NEXT: .functype i32_trunc_u_f64 (f64) -> (i32){{$}}
93 ; CHECK-NEXT: i32.trunc_u:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
93 ; CHECK-NEXT: i32.trunc_sat_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
9494 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
9595 define i32 @i32_trunc_u_f64(double %x) {
9696 %a = fptoui double %x to i32
9999
100100 ; CHECK-LABEL: i32_trunc_sat_u_f64:
101101 ; CHECK-NEXT: .functype i32_trunc_sat_u_f64 (f64) -> (i32){{$}}
102 ; CHECK-NEXT: i32.trunc_u:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
102 ; CHECK-NEXT: i32.trunc_sat_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
103103 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
104104 declare i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double)
105105 define i32 @i32_trunc_sat_u_f64(double %x) {
109109
110110 ; CHECK-LABEL: i64_trunc_s_f32:
111111 ; CHECK-NEXT: .functype i64_trunc_s_f32 (f32) -> (i64){{$}}
112 ; CHECK-NEXT: i64.trunc_s:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
112 ; CHECK-NEXT: i64.trunc_sat_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
113113 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
114114 define i64 @i64_trunc_s_f32(float %x) {
115115 %a = fptosi float %x to i64
118118
119119 ; CHECK-LABEL: i64_trunc_sat_s_f32:
120120 ; CHECK-NEXT: .functype i64_trunc_sat_s_f32 (f32) -> (i64){{$}}
121 ; CHECK-NEXT: i64.trunc_s:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
121 ; CHECK-NEXT: i64.trunc_sat_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
122122 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
123123 declare i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float)
124124 define i64 @i64_trunc_sat_s_f32(float %x) {
128128
129129 ; CHECK-LABEL: i64_trunc_u_f32:
130130 ; CHECK-NEXT: .functype i64_trunc_u_f32 (f32) -> (i64){{$}}
131 ; CHECK-NEXT: i64.trunc_u:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
131 ; CHECK-NEXT: i64.trunc_sat_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
132132 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
133133 define i64 @i64_trunc_u_f32(float %x) {
134134 %a = fptoui float %x to i64
137137
138138 ; CHECK-LABEL: i64_trunc_sat_u_f32:
139139 ; CHECK-NEXT: .functype i64_trunc_sat_u_f32 (f32) -> (i64){{$}}
140 ; CHECK-NEXT: i64.trunc_u:sat/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
140 ; CHECK-NEXT: i64.trunc_sat_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
141141 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
142142 declare i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float)
143143 define i64 @i64_trunc_sat_u_f32(float %x) {
147147
148148 ; CHECK-LABEL: i64_trunc_s_f64:
149149 ; CHECK-NEXT: .functype i64_trunc_s_f64 (f64) -> (i64){{$}}
150 ; CHECK-NEXT: i64.trunc_s:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
150 ; CHECK-NEXT: i64.trunc_sat_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
151151 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
152152 define i64 @i64_trunc_s_f64(double %x) {
153153 %a = fptosi double %x to i64
156156
157157 ; CHECK-LABEL: i64_trunc_sat_s_f64:
158158 ; CHECK-NEXT: .functype i64_trunc_sat_s_f64 (f64) -> (i64){{$}}
159 ; CHECK-NEXT: i64.trunc_s:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
159 ; CHECK-NEXT: i64.trunc_sat_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
160160 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
161161 declare i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double)
162162 define i64 @i64_trunc_sat_s_f64(double %x) {
166166
167167 ; CHECK-LABEL: i64_trunc_u_f64:
168168 ; CHECK-NEXT: .functype i64_trunc_u_f64 (f64) -> (i64){{$}}
169 ; CHECK-NEXT: i64.trunc_u:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
169 ; CHECK-NEXT: i64.trunc_sat_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
170170 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
171171 define i64 @i64_trunc_u_f64(double %x) {
172172 %a = fptoui double %x to i64
175175
176176 ; CHECK-LABEL: i64_trunc_sat_u_f64:
177177 ; CHECK-NEXT: .functype i64_trunc_sat_u_f64 (f64) -> (i64){{$}}
178 ; CHECK-NEXT: i64.trunc_u:sat/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
178 ; CHECK-NEXT: i64.trunc_sat_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
179179 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
180180 declare i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double)
181181 define i64 @i64_trunc_sat_u_f64(double %x) {
185185
186186 ; CHECK-LABEL: f32_convert_s_i32:
187187 ; CHECK-NEXT: .functype f32_convert_s_i32 (i32) -> (f32){{$}}
188 ; CHECK-NEXT: f32.convert_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
188 ; CHECK-NEXT: f32.convert_i32_s $push[[NUM:[0-9]+]]=, $0{{$}}
189189 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
190190 define float @f32_convert_s_i32(i32 %x) {
191191 %a = sitofp i32 %x to float
194194
195195 ; CHECK-LABEL: f32_convert_u_i32:
196196 ; CHECK-NEXT: .functype f32_convert_u_i32 (i32) -> (f32){{$}}
197 ; CHECK-NEXT: f32.convert_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
197 ; CHECK-NEXT: f32.convert_i32_u $push[[NUM:[0-9]+]]=, $0{{$}}
198198 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
199199 define float @f32_convert_u_i32(i32 %x) {
200200 %a = uitofp i32 %x to float
203203
204204 ; CHECK-LABEL: f64_convert_s_i32:
205205 ; CHECK-NEXT: .functype f64_convert_s_i32 (i32) -> (f64){{$}}
206 ; CHECK-NEXT: f64.convert_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
206 ; CHECK-NEXT: f64.convert_i32_s $push[[NUM:[0-9]+]]=, $0{{$}}
207207 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
208208 define double @f64_convert_s_i32(i32 %x) {
209209 %a = sitofp i32 %x to double
212212
213213 ; CHECK-LABEL: f64_convert_u_i32:
214214 ; CHECK-NEXT: .functype f64_convert_u_i32 (i32) -> (f64){{$}}
215 ; CHECK-NEXT: f64.convert_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
215 ; CHECK-NEXT: f64.convert_i32_u $push[[NUM:[0-9]+]]=, $0{{$}}
216216 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
217217 define double @f64_convert_u_i32(i32 %x) {
218218 %a = uitofp i32 %x to double
221221
222222 ; CHECK-LABEL: f32_convert_s_i64:
223223 ; CHECK-NEXT: .functype f32_convert_s_i64 (i64) -> (f32){{$}}
224 ; CHECK-NEXT: f32.convert_s/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
224 ; CHECK-NEXT: f32.convert_i64_s $push[[NUM:[0-9]+]]=, $0{{$}}
225225 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
226226 define float @f32_convert_s_i64(i64 %x) {
227227 %a = sitofp i64 %x to float
230230
231231 ; CHECK-LABEL: f32_convert_u_i64:
232232 ; CHECK-NEXT: .functype f32_convert_u_i64 (i64) -> (f32){{$}}
233 ; CHECK-NEXT: f32.convert_u/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
233 ; CHECK-NEXT: f32.convert_i64_u $push[[NUM:[0-9]+]]=, $0{{$}}
234234 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
235235 define float @f32_convert_u_i64(i64 %x) {
236236 %a = uitofp i64 %x to float
239239
240240 ; CHECK-LABEL: f64_convert_s_i64:
241241 ; CHECK-NEXT: .functype f64_convert_s_i64 (i64) -> (f64){{$}}
242 ; CHECK-NEXT: f64.convert_s/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
242 ; CHECK-NEXT: f64.convert_i64_s $push[[NUM:[0-9]+]]=, $0{{$}}
243243 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
244244 define double @f64_convert_s_i64(i64 %x) {
245245 %a = sitofp i64 %x to double
248248
249249 ; CHECK-LABEL: f64_convert_u_i64:
250250 ; CHECK-NEXT: .functype f64_convert_u_i64 (i64) -> (f64){{$}}
251 ; CHECK-NEXT: f64.convert_u/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
251 ; CHECK-NEXT: f64.convert_i64_u $push[[NUM:[0-9]+]]=, $0{{$}}
252252 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
253253 define double @f64_convert_u_i64(i64 %x) {
254254 %a = uitofp i64 %x to double
257257
258258 ; CHECK-LABEL: f64_promote_f32:
259259 ; CHECK-NEXT: .functype f64_promote_f32 (f32) -> (f64){{$}}
260 ; CHECK-NEXT: f64.promote/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
260 ; CHECK-NEXT: f64.promote_f32 $push[[NUM:[0-9]+]]=, $0{{$}}
261261 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
262262 define double @f64_promote_f32(float %x) {
263263 %a = fpext float %x to double
266266
267267 ; CHECK-LABEL: f32_demote_f64:
268268 ; CHECK-NEXT: .functype f32_demote_f64 (f64) -> (f32){{$}}
269 ; CHECK-NEXT: f32.demote/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
269 ; CHECK-NEXT: f32.demote_f64 $push[[NUM:[0-9]+]]=, $0{{$}}
270270 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
271271 define float @f32_demote_f64(double %x) {
272272 %a = fptrunc double %x to float
277277 ; we need to patterm-match back to a specific instruction.
278278
279279 ; CHECK-LABEL: anyext:
280 ; CHECK: i64.extend_u/i32 $push0=, $0{{$}}
280 ; CHECK: i64.extend_i32_u $push0=, $0{{$}}
281281 define i64 @anyext(i32 %x) {
282282 %y = sext i32 %x to i64
283283 %w = shl i64 %y, 32
285285 }
286286
287287 ; CHECK-LABEL: bitcast_i32_to_float:
288 ; CHECK: f32.reinterpret/i32 $push0=, $0{{$}}
288 ; CHECK: f32.reinterpret_i32 $push0=, $0{{$}}
289289 define float @bitcast_i32_to_float(i32 %a) {
290290 %t = bitcast i32 %a to float
291291 ret float %t
292292 }
293293
294294 ; CHECK-LABEL: bitcast_float_to_i32:
295 ; CHECK: i32.reinterpret/f32 $push0=, $0{{$}}
295 ; CHECK: i32.reinterpret_f32 $push0=, $0{{$}}
296296 define i32 @bitcast_float_to_i32(float %a) {
297297 %t = bitcast float %a to i32
298298 ret i32 %t
299299 }
300300
301301 ; CHECK-LABEL: bitcast_i64_to_double:
302 ; CHECK: f64.reinterpret/i64 $push0=, $0{{$}}
302 ; CHECK: f64.reinterpret_i64 $push0=, $0{{$}}
303303 define double @bitcast_i64_to_double(i64 %a) {
304304 %t = bitcast i64 %a to double
305305 ret double %t
306306 }
307307
308308 ; CHECK-LABEL: bitcast_double_to_i64:
309 ; CHECK: i64.reinterpret/f64 $push0=, $0{{$}}
309 ; CHECK: i64.reinterpret_f64 $push0=, $0{{$}}
310310 define i64 @bitcast_double_to_i64(double %a) {
311311 %t = bitcast double %a to i64
312312 ret i64 %t
99 declare float @copysignf(float, float) nounwind readnone
1010
1111 ; CHECK-LABEL: fold_promote:
12 ; CHECK: f64.promote/f32 $push0=, $pop{{[0-9]+}}{{$}}
12 ; CHECK: f64.promote_f32 $push0=, $pop{{[0-9]+}}{{$}}
1313 ; CHECK: f64.copysign $push1=, $pop{{[0-9]+}}, $pop0{{$}}
1414 define double @fold_promote(double %a, float %b) {
1515 %c = fpext float %b to double
1818 }
1919
2020 ; CHECK-LABEL: fold_demote:{{$}}
21 ; CHECK: f32.demote/f64 $push0=, $pop{{[0-9]+}}{{$}}
21 ; CHECK: f32.demote_f64 $push0=, $pop{{[0-9]+}}{{$}}
2222 ; CHECK: f32.copysign $push1=, $pop{{[0-9]+}}, $pop0{{$}}
2323 define float @fold_demote(float %a, double %b) {
2424 %c = fptrunc double %b to float
1111 declare void @llvm.wasm.throw(i32, i8*)
1212
1313 ; CHECK-LABEL: test_throw:
14 ; CHECK: get_local $push0=, 0
14 ; CHECK: local.get $push0=, 0
1515 ; CHECK-NEXT: throw __cpp_exception@EVENT, $pop0
1616 ; CHECK-NOT: unreachable
1717 define void @test_throw(i8* %p) {
2020 }
2121
2222 ; CHECK-LABEL: test_catch_rethrow:
23 ; CHECK: get_global $push{{.+}}=, __stack_pointer@GLOBAL
23 ; CHECK: global.get $push{{.+}}=, __stack_pointer@GLOBAL
2424 ; CHECK: try
2525 ; CHECK: call foo@FUNCTION
2626 ; CHECK: i32.catch $push{{.+}}=, 0
27 ; CHECK: set_global __stack_pointer@GLOBAL
27 ; CHECK: global.set __stack_pointer@GLOBAL
2828 ; CHECK-DAG: i32.store __wasm_lpad_context
2929 ; CHECK-DAG: i32.store __wasm_lpad_context+4
3030 ; CHECK: i32.call $push{{.+}}=, _Unwind_CallPersonality@FUNCTION
6666 ; CHECK: try
6767 ; CHECK: call foo@FUNCTION
6868 ; CHECK: catch_all
69 ; CHECK: set_global __stack_pointer@GLOBAL
69 ; CHECK: global.set __stack_pointer@GLOBAL
7070 ; CHECK: i32.call $push{{.+}}=, _ZN7CleanupD1Ev@FUNCTION
7171 ; CHECK: rethrow
7272 ; CHECK: end_try
164164 ; CHECK: try
165165 ; CHECK: call foo@FUNCTION
166166 ; CHECK: i32.catch
167 ; CHECK-NOT: get_global $push{{.+}}=, __stack_pointer@GLOBAL
168 ; CHECK: set_global __stack_pointer@GLOBAL
167 ; CHECK-NOT: global.get $push{{.+}}=, __stack_pointer@GLOBAL
168 ; CHECK: global.set __stack_pointer@GLOBAL
169169 ; CHECK: try
170170 ; CHECK: call foo@FUNCTION
171171 ; CHECK: catch_all
172 ; CHECK-NOT: get_global $push{{.+}}=, __stack_pointer@GLOBAL
173 ; CHECK: set_global __stack_pointer@GLOBAL
172 ; CHECK-NOT: global.get $push{{.+}}=, __stack_pointer@GLOBAL
173 ; CHECK: global.set __stack_pointer@GLOBAL
174174 ; CHECK: call __cxa_end_catch@FUNCTION
175 ; CHECK-NOT: set_global __stack_pointer@GLOBAL, $pop{{.+}}
175 ; CHECK-NOT: global.set __stack_pointer@GLOBAL, $pop{{.+}}
176176 ; CHECK: end_try
177 ; CHECK-NOT: set_global __stack_pointer@GLOBAL, $pop{{.+}}
177 ; CHECK-NOT: global.set __stack_pointer@GLOBAL, $pop{{.+}}
178178 ; CHECK: end_try
179179 define void @test_no_prolog_epilog_in_ehpad() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
180180 entry:
225225 ; CHECK: try
226226 ; CHECK: call foo@FUNCTION
227227 ; CHECK: end_try
228 ; CHECK-NOT: set_global __stack_pointer@GLOBAL
228 ; CHECK-NOT: global.set __stack_pointer@GLOBAL
229229 ; CHECK: return
230230 define void @no_sp_writeback() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
231231 entry:
77
88 ; CHECK-LABEL: demote:
99 ; CHECK-NEXT: .functype demote (f32) -> (f32){{$}}
10 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
10 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
1111 ; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, __gnu_f2h_ieee@FUNCTION, $pop[[L0]]{{$}}
1212 ; CHECK-NEXT: f32.call $push[[L2:[0-9]+]]=, __gnu_h2f_ieee@FUNCTION, $pop[[L1]]{{$}}
1313 ; CHECK-NEXT: return $pop[[L2]]{{$}}
1818
1919 ; CHECK-LABEL: promote:
2020 ; CHECK-NEXT: .functype promote (f32) -> (f32){{$}}
21 ; CHECK-NEXT: get_local $push0=, 0{{$}}
21 ; CHECK-NEXT: local.get $push0=, 0{{$}}
2222 ; CHECK-NEXT: return $pop0{{$}}
2323 define float @promote(half %f) {
2424 %t = fpext half %f to float
1616
1717 ; CHECK-LABEL: fadd32:
1818 ; CHECK-NEXT: .functype fadd32 (f32, f32) -> (f32){{$}}
19 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
20 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
19 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
20 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
2121 ; CHECK-NEXT: f32.add $push[[LR:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
2222 ; CHECK-NEXT: return $pop[[LR]]{{$}}
2323 define float @fadd32(float %x, float %y) {
1616
1717 ; CHECK-LABEL: fadd64:
1818 ; CHECK-NEXT: .functype fadd64 (f64, f64) -> (f64){{$}}
19 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
20 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
19 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
20 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
2121 ; CHECK-NEXT: f64.add $push[[LR:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
2222 ; CHECK-NEXT: return $pop[[LR]]{{$}}
2323 define double @fadd64(double %x, double %y) {
88
99 ; CHECK-LABEL: add:
1010 ; CHECK-NEXT: .functype add (i32, i32) -> (i32){{$}}
11 ; CHECK-NEXT: get_local $push2=, 0{{$}}
12 ; CHECK-NEXT: get_local $push1=, 1{{$}}
11 ; CHECK-NEXT: local.get $push2=, 0{{$}}
12 ; CHECK-NEXT: local.get $push1=, 1{{$}}
1313 ; CHECK-NEXT: i32.add $push0=, $pop2, $pop1{{$}}
1414 ; CHECK-NEXT: end_function
1515 define i24 @add(i24 %x, i24 %y) {
2020 }
2121
2222 ; CHECK-LABEL: bitcast_i32_f32:
23 ; CHECK: i32.reinterpret/f32 $push{{[0-9]+}}=, $0{{$}}
23 ; CHECK: i32.reinterpret_f32 $push{{[0-9]+}}=, $0{{$}}
2424 define i32 @bitcast_i32_f32(float %x) {
2525 %y = bitcast float %x to i32
2626 ret i32 %y
2727 }
2828
2929 ; CHECK-LABEL: bitcast_f32_i32:
30 ; CHECK: f32.reinterpret/i32 $push{{[0-9]+}}=, $0{{$}}
30 ; CHECK: f32.reinterpret_i32 $push{{[0-9]+}}=, $0{{$}}
3131 define float @bitcast_f32_i32(i32 %x) {
3232 %y = bitcast i32 %x to float
3333 ret float %y
3434 }
3535
3636 ; CHECK-LABEL: bitcast_i64_f64:
37 ; CHECK: i64.reinterpret/f64 $push{{[0-9]+}}=, $0{{$}}
37 ; CHECK: i64.reinterpret_f64 $push{{[0-9]+}}=, $0{{$}}
3838 define i64 @bitcast_i64_f64(double %x) {
3939 %y = bitcast double %x to i64
4040 ret i64 %y
4141 }
4242
4343 ; CHECK-LABEL: bitcast_f64_i64:
44 ; CHECK: f64.reinterpret/i64 $push{{[0-9]+}}=, $0{{$}}
44 ; CHECK: f64.reinterpret_i64 $push{{[0-9]+}}=, $0{{$}}
4545 define double @bitcast_f64_i64(i64 %x) {
4646 %y = bitcast i64 %x to double
4747 ret double %y
7878 }
7979
8080 ; CHECK-LABEL: test_varargs:
81 ; CHECK: set_global
81 ; CHECK: global.set
8282 ; CHECK: i32.const $push[[L3:[0-9]+]]=, 0{{$}}
8383 ; CHECK-NEXT: call .Lvararg_bitcast@FUNCTION, $pop[[L3]]{{$}}
8484 ; CHECK-NEXT: i32.const $push[[L4:[0-9]+]]=, 0{{$}}
198198 ; CHECK-LABEL: .Lfoo1_bitcast:
199199 ; CHECK-NEXT: .functype .Lfoo1_bitcast () -> (i32)
200200 ; CHECK-NEXT: call foo1@FUNCTION{{$}}
201 ; CHECK-NEXT: copy_local $push0=, $0
202 ; CHECK-NEXT: end_function
201 ; CHECK-NEXT: local.copy $push0=, $0
202 ; CHECK-NEXT: end_function
1010
1111 ; CHECK-LABEL: add32:
1212 ; CHECK-NEXT: .functype add32 (i32, i32) -> (i32){{$}}
13 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
14 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
13 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
14 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
1515 ; CHECK-NEXT: i32.add $push0=, $pop[[L0]], $pop[[L1]]{{$}}
1616 ; CHECK-NEXT: return $pop0{{$}}
1717 define i32 @add32(i32 %x, i32 %y) {
2121
2222 ; CHECK-LABEL: sub32:
2323 ; CHECK-NEXT: .functype sub32 (i32, i32) -> (i32){{$}}
24 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
25 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
24 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
25 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
2626 ; CHECK-NEXT: i32.sub $push0=, $pop[[L0]], $pop[[L1]]{{$}}
2727 ; CHECK-NEXT: return $pop0{{$}}
2828 define i32 @sub32(i32 %x, i32 %y) {
3232
3333 ; CHECK-LABEL: mul32:
3434 ; CHECK-NEXT: .functype mul32 (i32, i32) -> (i32){{$}}
35 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
36 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
35 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
36 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
3737 ; CHECK-NEXT: i32.mul $push0=, $pop[[L0]], $pop[[L1]]{{$}}
3838 ; CHECK-NEXT: return $pop0{{$}}
3939 define i32 @mul32(i32 %x, i32 %y) {
4343
4444 ; CHECK-LABEL: sdiv32:
4545 ; CHECK-NEXT: .functype sdiv32 (i32, i32) -> (i32){{$}}
46 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
47 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
46 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
47 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
4848 ; CHECK-NEXT: i32.div_s $push0=, $pop[[L0]], $pop[[L1]]{{$}}
4949 ; CHECK-NEXT: return $pop0{{$}}
5050 define i32 @sdiv32(i32 %x, i32 %y) {
5454
5555 ; CHECK-LABEL: udiv32:
5656 ; CHECK-NEXT: .functype udiv32 (i32, i32) -> (i32){{$}}
57 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
58 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
57 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
58 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
5959 ; CHECK-NEXT: i32.div_u $push0=, $pop[[L0]], $pop[[L1]]{{$}}
6060 ; CHECK-NEXT: return $pop0{{$}}
6161 define i32 @udiv32(i32 %x, i32 %y) {
6565
6666 ; CHECK-LABEL: srem32:
6767 ; CHECK-NEXT: .functype srem32 (i32, i32) -> (i32){{$}}
68 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
69 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
68 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
69 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
7070 ; CHECK-NEXT: i32.rem_s $push0=, $pop[[L0]], $pop[[L1]]{{$}}
7171 ; CHECK-NEXT: return $pop0{{$}}
7272 define i32 @srem32(i32 %x, i32 %y) {
7676
7777 ; CHECK-LABEL: urem32:
7878 ; CHECK-NEXT: .functype urem32 (i32, i32) -> (i32){{$}}
79 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
80 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
79 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
80 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
8181 ; CHECK-NEXT: i32.rem_u $push0=, $pop[[L0]], $pop[[L1]]{{$}}
8282 ; CHECK-NEXT: return $pop0{{$}}
8383 define i32 @urem32(i32 %x, i32 %y) {
8787
8888 ; CHECK-LABEL: and32:
8989 ; CHECK-NEXT: .functype and32 (i32, i32) -> (i32){{$}}
90 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
91 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
90 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
91 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
9292 ; CHECK-NEXT: i32.and $push0=, $pop[[L0]], $pop[[L1]]{{$}}
9393 ; CHECK-NEXT: return $pop0{{$}}
9494 define i32 @and32(i32 %x, i32 %y) {
9898
9999 ; CHECK-LABEL: or32:
100100 ; CHECK-NEXT: .functype or32 (i32, i32) -> (i32){{$}}
101 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
101 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
103103 ; CHECK-NEXT: i32.or $push0=, $pop[[L0]], $pop[[L1]]{{$}}
104104 ; CHECK-NEXT: return $pop0{{$}}
105105 define i32 @or32(i32 %x, i32 %y) {
109109
110110 ; CHECK-LABEL: xor32:
111111 ; CHECK-NEXT: .functype xor32 (i32, i32) -> (i32){{$}}
112 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
113 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
112 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
113 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
114114 ; CHECK-NEXT: i32.xor $push0=, $pop[[L0]], $pop[[L1]]{{$}}
115115 ; CHECK-NEXT: return $pop0{{$}}
116116 define i32 @xor32(i32 %x, i32 %y) {
120120
121121 ; CHECK-LABEL: shl32:
122122 ; CHECK-NEXT: .functype shl32 (i32, i32) -> (i32){{$}}
123 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
124 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
123 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
124 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
125125 ; CHECK-NEXT: i32.shl $push0=, $pop[[L0]], $pop[[L1]]{{$}}
126126 ; CHECK-NEXT: return $pop0{{$}}
127127 define i32 @shl32(i32 %x, i32 %y) {
131131
132132 ; CHECK-LABEL: shr32:
133133 ; CHECK-NEXT: .functype shr32 (i32, i32) -> (i32){{$}}
134 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
135 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
134 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
135 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
136136 ; CHECK-NEXT: i32.shr_u $push0=, $pop[[L0]], $pop[[L1]]{{$}}
137137 ; CHECK-NEXT: return $pop0{{$}}
138138 define i32 @shr32(i32 %x, i32 %y) {
142142
143143 ; CHECK-LABEL: sar32:
144144 ; CHECK-NEXT: .functype sar32 (i32, i32) -> (i32){{$}}
145 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
146 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
145 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
146 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
147147 ; CHECK-NEXT: i32.shr_s $push0=, $pop[[L0]], $pop[[L1]]{{$}}
148148 ; CHECK-NEXT: return $pop0{{$}}
149149 define i32 @sar32(i32 %x, i32 %y) {
153153
154154 ; CHECK-LABEL: clz32:
155155 ; CHECK-NEXT: .functype clz32 (i32) -> (i32){{$}}
156 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
156 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
157157 ; CHECK-NEXT: i32.clz $push0=, $pop[[L0]]{{$}}
158158 ; CHECK-NEXT: return $pop0{{$}}
159159 define i32 @clz32(i32 %x) {
163163
164164 ; CHECK-LABEL: clz32_zero_undef:
165165 ; CHECK-NEXT: .functype clz32_zero_undef (i32) -> (i32){{$}}
166 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
166 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
167167 ; CHECK-NEXT: i32.clz $push0=, $pop[[L0]]{{$}}
168168 ; CHECK-NEXT: return $pop0{{$}}
169169 define i32 @clz32_zero_undef(i32 %x) {
173173
174174 ; CHECK-LABEL: ctz32:
175175 ; CHECK-NEXT: .functype ctz32 (i32) -> (i32){{$}}
176 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
176 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
177177 ; CHECK-NEXT: i32.ctz $push0=, $pop[[L0]]{{$}}
178178 ; CHECK-NEXT: return $pop0{{$}}
179179 define i32 @ctz32(i32 %x) {
183183
184184 ; CHECK-LABEL: ctz32_zero_undef:
185185 ; CHECK-NEXT: .functype ctz32_zero_undef (i32) -> (i32){{$}}
186 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
186 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
187187 ; CHECK-NEXT: i32.ctz $push0=, $pop[[L0]]{{$}}
188188 ; CHECK-NEXT: return $pop0{{$}}
189189 define i32 @ctz32_zero_undef(i32 %x) {
193193
194194 ; CHECK-LABEL: popcnt32:
195195 ; CHECK-NEXT: .functype popcnt32 (i32) -> (i32){{$}}
196 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
196 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
197197 ; CHECK-NEXT: i32.popcnt $push0=, $pop[[L0]]{{$}}
198198 ; CHECK-NEXT: return $pop0{{$}}
199199 define i32 @popcnt32(i32 %x) {
203203
204204 ; CHECK-LABEL: eqz32:
205205 ; CHECK-NEXT: .functype eqz32 (i32) -> (i32){{$}}
206 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
206 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
207207 ; CHECK-NEXT: i32.eqz $push0=, $pop[[L0]]{{$}}
208208 ; CHECK-NEXT: return $pop0{{$}}
209209 define i32 @eqz32(i32 %x) {
214214
215215 ; CHECK-LABEL: rotl:
216216 ; CHECK-NEXT: .functype rotl (i32, i32) -> (i32){{$}}
217 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
218 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
217 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
218 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
219219 ; CHECK-NEXT: i32.rotl $push0=, $pop[[L0]], $pop[[L1]]
220220 ; CHECK-NEXT: return $pop0{{$}}
221221 define i32 @rotl(i32 %x, i32 %y) {
228228
229229 ; CHECK-LABEL: masked_rotl:
230230 ; CHECK-NEXT: .functype masked_rotl (i32, i32) -> (i32){{$}}
231 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
232 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
231 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
232 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
233233 ; CHECK-NEXT: i32.rotl $push0=, $pop[[L0]], $pop[[L1]]
234234 ; CHECK-NEXT: return $pop0{{$}}
235235 define i32 @masked_rotl(i32 %x, i32 %y) {
243243
244244 ; CHECK-LABEL: rotr:
245245 ; CHECK-NEXT: .functype rotr (i32, i32) -> (i32){{$}}
246 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
247 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
246 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
247 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
248248 ; CHECK-NEXT: i32.rotr $push0=, $pop[[L0]], $pop[[L1]]
249249 ; CHECK-NEXT: return $pop0{{$}}
250250 define i32 @rotr(i32 %x, i32 %y) {
257257
258258 ; CHECK-LABEL: masked_rotr:
259259 ; CHECK-NEXT: .functype masked_rotr (i32, i32) -> (i32){{$}}
260 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
261 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
260 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
261 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
262262 ; CHECK-NEXT: i32.rotr $push0=, $pop[[L0]], $pop[[L1]]
263263 ; CHECK-NEXT: return $pop0{{$}}
264264 define i32 @masked_rotr(i32 %x, i32 %y) {
1010
1111 ; CHECK-LABEL: add64:
1212 ; CHECK-NEXT: .functype add64 (i64, i64) -> (i64){{$}}
13 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
14 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
13 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
14 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
1515 ; CHECK-NEXT: i64.add $push0=, $pop[[L0]], $pop[[L1]]{{$}}
1616 ; CHECK-NEXT: return $pop0{{$}}
1717 define i64 @add64(i64 %x, i64 %y) {
2121
2222 ; CHECK-LABEL: sub64:
2323 ; CHECK-NEXT: .functype sub64 (i64, i64) -> (i64){{$}}
24 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
25 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
24 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
25 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
2626 ; CHECK-NEXT: i64.sub $push0=, $pop[[L0]], $pop[[L1]]{{$}}
2727 ; CHECK-NEXT: return $pop0{{$}}
2828 define i64 @sub64(i64 %x, i64 %y) {
3232
3333 ; CHECK-LABEL: mul64:
3434 ; CHECK-NEXT: .functype mul64 (i64, i64) -> (i64){{$}}
35 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
36 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
35 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
36 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
3737 ; CHECK-NEXT: i64.mul $push0=, $pop[[L0]], $pop[[L1]]{{$}}
3838 ; CHECK-NEXT: return $pop0{{$}}
3939 define i64 @mul64(i64 %x, i64 %y) {
4343
4444 ; CHECK-LABEL: sdiv64:
4545 ; CHECK-NEXT: .functype sdiv64 (i64, i64) -> (i64){{$}}
46 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
47 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
46 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
47 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
4848 ; CHECK-NEXT: i64.div_s $push0=, $pop[[L0]], $pop[[L1]]{{$}}
4949 ; CHECK-NEXT: return $pop0{{$}}
5050 define i64 @sdiv64(i64 %x, i64 %y) {
5454
5555 ; CHECK-LABEL: udiv64:
5656 ; CHECK-NEXT: .functype udiv64 (i64, i64) -> (i64){{$}}
57 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
58 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
57 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
58 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
5959 ; CHECK-NEXT: i64.div_u $push0=, $pop[[L0]], $pop[[L1]]{{$}}
6060 ; CHECK-NEXT: return $pop0{{$}}
6161 define i64 @udiv64(i64 %x, i64 %y) {
6565
6666 ; CHECK-LABEL: srem64:
6767 ; CHECK-NEXT: .functype srem64 (i64, i64) -> (i64){{$}}
68 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
69 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
68 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
69 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
7070 ; CHECK-NEXT: i64.rem_s $push0=, $pop[[L0]], $pop[[L1]]{{$}}
7171 ; CHECK-NEXT: return $pop0{{$}}
7272 define i64 @srem64(i64 %x, i64 %y) {
7676
7777 ; CHECK-LABEL: urem64:
7878 ; CHECK-NEXT: .functype urem64 (i64, i64) -> (i64){{$}}
79 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
80 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
79 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
80 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
8181 ; CHECK-NEXT: i64.rem_u $push0=, $pop[[L0]], $pop[[L1]]{{$}}
8282 ; CHECK-NEXT: return $pop0{{$}}
8383 define i64 @urem64(i64 %x, i64 %y) {
8787
8888 ; CHECK-LABEL: and64:
8989 ; CHECK-NEXT: .functype and64 (i64, i64) -> (i64){{$}}
90 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
91 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
90 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
91 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
9292 ; CHECK-NEXT: i64.and $push0=, $pop[[L0]], $pop[[L1]]{{$}}
9393 ; CHECK-NEXT: return $pop0{{$}}
9494 define i64 @and64(i64 %x, i64 %y) {
9898
9999 ; CHECK-LABEL: or64:
100100 ; CHECK-NEXT: .functype or64 (i64, i64) -> (i64){{$}}
101 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
101 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
103103 ; CHECK-NEXT: i64.or $push0=, $pop[[L0]], $pop[[L1]]{{$}}
104104 ; CHECK-NEXT: return $pop0{{$}}
105105 define i64 @or64(i64 %x, i64 %y) {
109109
110110 ; CHECK-LABEL: xor64:
111111 ; CHECK-NEXT: .functype xor64 (i64, i64) -> (i64){{$}}
112 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
113 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
112 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
113 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
114114 ; CHECK-NEXT: i64.xor $push0=, $pop[[L0]], $pop[[L1]]{{$}}
115115 ; CHECK-NEXT: return $pop0{{$}}
116116 define i64 @xor64(i64 %x, i64 %y) {
120120
121121