[llvm] [WebAssembly][GlobalISel] Add legalization & selection of most integer ops (PR #190234)
Demetrius Kanios via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 3 11:22:38 PDT 2026
https://github.com/QuantumSegfault updated https://github.com/llvm/llvm-project/pull/190234
>From 1793931d81517b9274b691ae413700deadd4d77c Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Thu, 2 Apr 2026 11:54:20 -0700
Subject: [PATCH 1/3] Add legalization, regbank, and isel for most integer ops.
---
.../GISel/WebAssemblyInstructionSelector.cpp | 52 +++
.../GISel/WebAssemblyLegalizerInfo.cpp | 61 ++-
.../GISel/WebAssemblyLegalizerInfo.h | 3 +
.../GISel/WebAssemblyRegisterBankInfo.cpp | 41 +-
.../WebAssembly/WebAssemblyInstrInteger.td | 8 +
.../GlobalISel/instruction-select/bitwise.mir | 433 +++++++++++++++++-
.../GlobalISel/instruction-select/consts.mir | 76 +++
.../instruction-select/ext-trunc.mir | 186 ++++++++
.../instruction-select/int-arithmetic.mir | 271 ++++++++++-
.../WebAssembly/GlobalISel/legalizer/add.mir | 61 ++-
.../WebAssembly/GlobalISel/legalizer/and.mir | 116 +++++
.../GlobalISel/legalizer/anyext.mir | 95 ++++
.../WebAssembly/GlobalISel/legalizer/ashr.mir | 331 +++++++++++++
.../GlobalISel/legalizer/constant.mir | 145 ++++++
.../WebAssembly/GlobalISel/legalizer/ctlz.mir | 152 ++++++
.../GlobalISel/legalizer/ctlz_zero_undef.mir | 148 ++++++
.../GlobalISel/legalizer/ctpop.mir | 148 ++++++
.../WebAssembly/GlobalISel/legalizer/cttz.mir | 148 ++++++
.../GlobalISel/legalizer/cttz_zero_undef.mir | 144 ++++++
.../WebAssembly/GlobalISel/legalizer/fshl.mir | 393 ++++++++++++++++
.../WebAssembly/GlobalISel/legalizer/fshr.mir | 389 ++++++++++++++++
.../GlobalISel/legalizer/implicit_def.mir | 72 +++
.../WebAssembly/GlobalISel/legalizer/lshr.mir | 286 ++++++++++++
.../WebAssembly/GlobalISel/legalizer/mul.mir | 91 ++++
.../WebAssembly/GlobalISel/legalizer/or.mir | 117 +++++
.../WebAssembly/GlobalISel/legalizer/rotl.mir | 303 ++++++++++++
.../WebAssembly/GlobalISel/legalizer/rotr.mir | 303 ++++++++++++
.../WebAssembly/GlobalISel/legalizer/sdiv.mir | 126 +++++
.../WebAssembly/GlobalISel/legalizer/sext.mir | 138 ++++++
.../GlobalISel/legalizer/sext_inreg.mir | 181 ++++++++
.../WebAssembly/GlobalISel/legalizer/shl.mir | 278 +++++++++++
.../WebAssembly/GlobalISel/legalizer/srem.mir | 126 +++++
.../WebAssembly/GlobalISel/legalizer/sub.mir | 91 ++++
.../GlobalISel/legalizer/trunc.mir | 95 ++++
.../WebAssembly/GlobalISel/legalizer/udiv.mir | 99 ++++
.../WebAssembly/GlobalISel/legalizer/urem.mir | 99 ++++
.../WebAssembly/GlobalISel/legalizer/xor.mir | 116 +++++
.../WebAssembly/GlobalISel/legalizer/zext.mir | 103 +++++
.../GlobalISel/regbankselect/bitwise.mir | 414 ++++++++++++++++-
.../GlobalISel/regbankselect/consts.mir | 72 +++
.../GlobalISel/regbankselect/ext-trunc.mir | 177 +++++++
.../regbankselect/int-arithmetic.mir | 259 ++++++++++-
42 files changed, 6913 insertions(+), 34 deletions(-)
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/consts.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/ext-trunc.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/and.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/anyext.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ashr.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/constant.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctpop.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshl.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshr.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/implicit_def.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/lshr.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/mul.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/or.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotl.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotr.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sdiv.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext_inreg.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/shl.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/srem.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sub.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/trunc.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/udiv.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/urem.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/xor.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/zext.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/consts.mir
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/ext-trunc.mir
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp
index 463d3977c329d..7359156ccf60c 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
+#include "llvm/Support/ErrorHandling.h"
#define DEBUG_TYPE "wasm-isel"
@@ -83,7 +84,35 @@ WebAssemblyInstructionSelector::WebAssemblyInstructionSelector(
{
}
+static const TargetRegisterClass &getRegClassForBank(const RegisterBank &RB) {
+ switch (RB.getID()) {
+ case WebAssembly::I32RegBankID:
+ return WebAssembly::I32RegClass;
+ case WebAssembly::I64RegBankID:
+ return WebAssembly::I64RegClass;
+ case WebAssembly::F32RegBankID:
+ return WebAssembly::F32RegClass;
+ case WebAssembly::F64RegBankID:
+ return WebAssembly::F64RegClass;
+ case WebAssembly::EXNREFRegBankID:
+ return WebAssembly::EXNREFRegClass;
+ case WebAssembly::EXTERNREFRegBankID:
+ return WebAssembly::EXTERNREFRegClass;
+ case WebAssembly::FUNCREFRegBankID:
+ return WebAssembly::FUNCREFRegClass;
+ case WebAssembly::V128RegBankID:
+ return WebAssembly::V128RegClass;
+ default:
+ reportFatalInternalError(
+ "Found unexpected RegisterBank in `getRegClassForBank`");
+ }
+}
+
bool WebAssemblyInstructionSelector::select(MachineInstr &I) {
+ MachineBasicBlock &MBB = *I.getParent();
+ MachineFunction &MF = *MBB.getParent();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+
if (!I.isPreISelOpcode()) {
return true;
}
@@ -91,6 +120,29 @@ bool WebAssemblyInstructionSelector::select(MachineInstr &I) {
if (selectImpl(I, *CoverageInfo))
return true;
+ using namespace TargetOpcode;
+
+ switch (I.getOpcode()) {
+ case G_IMPLICIT_DEF: {
+ const Register DefReg = I.getOperand(0).getReg();
+ const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(DefReg);
+
+ const TargetRegisterClass *DefRC =
+ dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
+
+ if (!DefRC) {
+ const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
+ DefRC = &getRegClassForBank(RB);
+ }
+
+ I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
+
+ return RBI.constrainGenericRegister(DefReg, *DefRC, MRI) != nullptr;
+ }
+ default:
+ break;
+ }
+
return false;
}
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
index ecbaf79db751d..0b9bbc1a6853a 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
@@ -12,6 +12,8 @@
#include "WebAssemblyLegalizerInfo.h"
#include "WebAssemblySubtarget.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#define DEBUG_TYPE "wasm-legalinfo"
@@ -25,18 +27,71 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
- getActionDefinitionsBuilder({G_CONSTANT, G_ADD, G_AND})
+ getActionDefinitionsBuilder({G_CONSTANT, G_IMPLICIT_DEF, G_ADD, G_SUB, G_MUL,
+ G_UDIV, G_SDIV, G_UREM, G_SREM, G_AND, G_OR,
+ G_XOR})
.legalFor({s32, s64})
.widenScalarToNextPow2(0)
.clampScalar(0, s32, s64);
- getActionDefinitionsBuilder({G_ASHR, G_SHL})
+ getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
.legalFor({{s32, s32}, {s64, s64}})
.widenScalarToNextPow2(0)
.clampScalar(0, s32, s64)
.scalarSameSizeAs(1, 0);
- getActionDefinitionsBuilder(G_SEXT_INREG).lower();
+ getActionDefinitionsBuilder(
+ {G_CTLZ, G_CTLZ_ZERO_UNDEF, G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTPOP})
+ .legalFor({{s32, s32}, {s64, s64}})
+ .widenScalarToNextPow2(1)
+ .clampScalar(1, s32, s64)
+ .scalarSameSizeAs(0, 1);
+
+ getActionDefinitionsBuilder({G_ROTL, G_ROTR})
+ .legalFor({{s32, s32}, {s64, s64}})
+ .scalarSameSizeAs(1, 0)
+ .lower();
+
+ getActionDefinitionsBuilder({G_FSHL, G_FSHR}).lower();
+
+ getActionDefinitionsBuilder({G_ANYEXT, G_SEXT, G_ZEXT})
+ .legalFor({{s64, s32}})
+ .clampScalar(0, s64, s64)
+ .clampScalar(1, s32, s32);
+
+ getActionDefinitionsBuilder(G_TRUNC)
+ .legalFor({{s32, s64}})
+ .clampScalar(0, s32, s32)
+ .clampScalar(1, s64, s64);
+
+ getActionDefinitionsBuilder(G_SEXT_INREG)
+ .clampScalar(0, s32, s64)
+ .customFor(ST.hasSignExt(), {s32, s64})
+ .lower();
getLegacyLegalizerInfo().computeTables();
}
+
+bool WebAssemblyLegalizerInfo::legalizeCustom(
+ LegalizerHelper &Helper, MachineInstr &MI,
+ LostDebugLocObserver &LocObserver) const {
+ switch (MI.getOpcode()) {
+ case TargetOpcode::G_SEXT_INREG: {
+ assert(MI.getOperand(2).isImm() && "Expected immediate");
+
+ // Mark only 8/16/32-bit SEXT_INREG as legal
+ auto [DstType, SrcType] = MI.getFirst2LLTs();
+ auto ExtFromWidth = MI.getOperand(2).getImm();
+
+ if (ExtFromWidth == 8 || ExtFromWidth == 16 ||
+ (DstType.getScalarSizeInBits() == 64 && ExtFromWidth == 32)) {
+ return true;
+ }
+
+ return Helper.lower(MI, 0, DstType);
+ }
+ default:
+ break;
+ }
+ return false;
+}
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h
index 61f4aa621d44f..45f21d7190abe 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h
@@ -24,6 +24,9 @@ class WebAssemblySubtarget;
class WebAssemblyLegalizerInfo : public LegalizerInfo {
public:
WebAssemblyLegalizerInfo(const WebAssemblySubtarget &ST);
+
+ bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
+ LostDebugLocObserver &LocObserver) const override;
};
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.cpp
index 4aaf04eb2496e..f7be420b49d2f 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.cpp
@@ -88,14 +88,51 @@ WebAssemblyRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
using namespace TargetOpcode;
switch (Opc) {
+ case G_CONSTANT:
+ OperandsMapping = getOperandsMapping({&Op0IntValueMapping, nullptr});
+ break;
+ case G_IMPLICIT_DEF:
+ OperandsMapping = &Op0IntValueMapping;
+ break;
case G_ADD:
+ case G_SUB:
+ case G_MUL:
+ case G_UDIV:
+ case G_SDIV:
+ case G_UREM:
+ case G_SREM:
case G_AND:
+ case G_OR:
+ case G_XOR:
case G_ASHR:
+ case G_LSHR:
case G_SHL:
+ case G_CTLZ:
+ case G_CTLZ_ZERO_UNDEF:
+ case G_CTTZ:
+ case G_CTTZ_ZERO_UNDEF:
+ case G_CTPOP:
+ case G_ROTL:
+ case G_ROTR:
OperandsMapping = &Op0IntValueMapping;
break;
- case G_CONSTANT:
- OperandsMapping = getOperandsMapping({&Op0IntValueMapping, nullptr});
+ case G_ZEXT:
+ case G_ANYEXT:
+ case G_SEXT:
+ case G_TRUNC: {
+ const LLT Op1Ty = MRI.getType(MI.getOperand(1).getReg());
+ unsigned Op1Size = Op1Ty.getSizeInBits();
+
+ auto &Op1IntValueMapping =
+ WebAssembly::ValueMappings[Op1Size == 64 ? WebAssembly::I64Idx
+ : WebAssembly::I32Idx];
+ OperandsMapping =
+ getOperandsMapping({&Op0IntValueMapping, &Op1IntValueMapping});
+ break;
+ }
+ case G_SEXT_INREG:
+ OperandsMapping =
+ getOperandsMapping({&Op0IntValueMapping, &Op0IntValueMapping, nullptr});
break;
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
index 991507e883f28..99ca22e21f70b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
@@ -82,10 +82,18 @@ defm LE_U : ComparisonInt<SETULE, "le_u", 0x4d, 0x58>;
defm GE_S : ComparisonInt<SETGE, "ge_s", 0x4e, 0x59>;
defm GE_U : ComparisonInt<SETUGE, "ge_u", 0x4f, 0x5a>;
+
defm CLZ : UnaryInt<ctlz, "clz ", 0x67, 0x79>;
+def : Pat<(ctlz_zero_undef I32:$src), (CLZ_I32 I32:$src)>;
+def : Pat<(ctlz_zero_undef I64:$src), (CLZ_I64 I64:$src)>;
+
defm CTZ : UnaryInt<cttz, "ctz ", 0x68, 0x7a>;
+def : Pat<(cttz_zero_undef I32:$src), (CTZ_I32 I32:$src)>;
+def : Pat<(cttz_zero_undef I64:$src), (CTZ_I64 I64:$src)>;
+
defm POPCNT : UnaryInt<ctpop, "popcnt", 0x69, 0x7b>;
+
defm EQZ_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
[(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
"i32.eqz \t$dst, $src", "i32.eqz", 0x45>;
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir
index c1c111606d15f..1a5943259b521 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir
@@ -23,7 +23,6 @@ body: |
%2:i32regbank(s32) = G_AND %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: and_i64
alignment: 1
@@ -47,6 +46,96 @@ body: |
RETURN %2(s64), implicit-def $arguments
...
+---
+name: or_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[OR_I32_:%[0-9]+]]:i32 = OR_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[OR_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_OR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: or_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[OR_I64_:%[0-9]+]]:i64 = OR_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[OR_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_OR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: xor_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR_I32_:%[0-9]+]]:i32 = XOR_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[XOR_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_XOR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: xor_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR_I64_:%[0-9]+]]:i64 = XOR_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[XOR_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_XOR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
---
name: shl_i32
alignment: 1
@@ -69,7 +158,6 @@ body: |
%2:i32regbank(s32) = G_SHL %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: shl_i64
alignment: 1
@@ -115,7 +203,6 @@ body: |
%2:i32regbank(s32) = G_ASHR %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: ashr_i64
alignment: 1
@@ -138,3 +225,343 @@ body: |
%2:i64regbank(s64) = G_ASHR %0, %1
RETURN %2(s64), implicit-def $arguments
...
+
+---
+name: lshr_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CONST_I32_:%[0-9]+]]:i32 = CONST_I32 5, implicit-def dead $arguments
+ ; CHECK-NEXT: [[SHR_U_I32_:%[0-9]+]]:i32 = SHR_U_I32 [[ARGUMENT_i32_]], [[CONST_I32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[SHR_U_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_CONSTANT i32 5
+ %2:i32regbank(s32) = G_LSHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: lshr_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CONST_I64_:%[0-9]+]]:i64 = CONST_I64 37, implicit-def dead $arguments
+ ; CHECK-NEXT: [[SHR_U_I64_:%[0-9]+]]:i64 = SHR_U_I64 [[ARGUMENT_i64_]], [[CONST_I64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[SHR_U_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_CONSTANT i64 37
+ %2:i64regbank(s64) = G_LSHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: ctlz_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CLZ_I32_:%[0-9]+]]:i32 = CLZ_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CLZ_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_CTLZ %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: ctlz_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CLZ_I64_:%[0-9]+]]:i64 = CLZ_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CLZ_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_CTLZ %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: ctlz_zundef_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CLZ_I32_:%[0-9]+]]:i32 = CLZ_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CLZ_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: ctlz_zundef_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CLZ_I64_:%[0-9]+]]:i64 = CLZ_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CLZ_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: cttz_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTZ_I32_:%[0-9]+]]:i32 = CTZ_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CTZ_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_CTTZ %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: cttz_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTZ_I64_:%[0-9]+]]:i64 = CTZ_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CTZ_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_CTTZ %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: cttz_zundef_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTZ_I32_:%[0-9]+]]:i32 = CTZ_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CTZ_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: cttz_zundef_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTZ_I64_:%[0-9]+]]:i64 = CTZ_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CTZ_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: ctpop_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[POPCNT_I32_:%[0-9]+]]:i32 = POPCNT_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[POPCNT_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_CTPOP %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: ctpop_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[POPCNT_I64_:%[0-9]+]]:i64 = POPCNT_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[POPCNT_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_CTPOP %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: rotl_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTL_I32_:%[0-9]+]]:i32 = ROTL_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[ROTL_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_ROTL %0, %1(s32)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: rotl_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTL_I64_:%[0-9]+]]:i64 = ROTL_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[ROTL_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_ROTL %0, %1(s64)
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: rotr_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTR_I32_:%[0-9]+]]:i32 = ROTR_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[ROTR_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_ROTR %0, %1(s32)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: rotr_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTR_I64_:%[0-9]+]]:i64 = ROTR_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[ROTR_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_ROTR %0, %1(s64)
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/consts.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/consts.mir
new file mode 100644
index 0000000000000..f3ee685d18a85
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/consts.mir
@@ -0,0 +1,76 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: const_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[CONST_I32_:%[0-9]+]]:i32 = CONST_I32 0, implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CONST_I32_]], implicit-def $arguments
+ %0:i32regbank(s32) = G_CONSTANT i32 0
+ RETURN %0(s32), implicit-def $arguments
+...
+---
+name: const_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[CONST_I64_:%[0-9]+]]:i64 = CONST_I64 0, implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[CONST_I64_]], implicit-def $arguments
+ %0:i64regbank(s64) = G_CONSTANT i64 0
+ RETURN %0(s64), implicit-def $arguments
+...
+
+---
+name: implicit_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:i32 = IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]], implicit-def $arguments
+ %0:i32regbank(s32) = G_IMPLICIT_DEF
+ RETURN %0(s32), implicit-def $arguments
+...
+---
+name: implicit_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:i64 = IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]], implicit-def $arguments
+ %0:i64regbank(s64) = G_IMPLICIT_DEF
+ RETURN %0(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/ext-trunc.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/ext-trunc.mir
new file mode 100644
index 0000000000000..6c150bd2884cf
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/ext-trunc.mir
@@ -0,0 +1,186 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: anyext
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: anyext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[I64_EXTEND_U_I32_:%[0-9]+]]:i64 = I64_EXTEND_U_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I64_EXTEND_U_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i64regbank(s64) = G_ANYEXT %0
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: sext
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[I64_EXTEND_S_I32_:%[0-9]+]]:i64 = I64_EXTEND_S_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I64_EXTEND_S_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i64regbank(s64) = G_SEXT %0
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: zext
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[I64_EXTEND_U_I32_:%[0-9]+]]:i64 = I64_EXTEND_U_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I64_EXTEND_U_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i64regbank(s64) = G_ZEXT %0
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: trunc
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[I32_WRAP_I64_:%[0-9]+]]:i32 = I32_WRAP_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I32_WRAP_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i32regbank(s32) = G_TRUNC %0
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i32_8
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i32_8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[I32_EXTEND8_S_I32_:%[0-9]+]]:i32 = I32_EXTEND8_S_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I32_EXTEND8_S_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_SEXT_INREG %0, 8
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: sext_inreg_i64_8
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i64_8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[I64_EXTEND8_S_I64_:%[0-9]+]]:i64 = I64_EXTEND8_S_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I64_EXTEND8_S_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_SEXT_INREG %0, 8
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i32_16
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i32_16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[I32_EXTEND16_S_I32_:%[0-9]+]]:i32 = I32_EXTEND16_S_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I32_EXTEND16_S_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32regbank(s32) = G_SEXT_INREG %0, 16
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: sext_inreg_i64_16
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i64_16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[I64_EXTEND16_S_I64_:%[0-9]+]]:i64 = I64_EXTEND16_S_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I64_EXTEND16_S_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_SEXT_INREG %0, 16
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i64_32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i64_32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[I64_EXTEND32_S_I64_:%[0-9]+]]:i64 = I64_EXTEND32_S_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[I64_EXTEND32_S_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64regbank(s64) = G_SEXT_INREG %0, 32
+ RETURN %1(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/int-arithmetic.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/int-arithmetic.mir
index 60c916c372636..2d13318da5a84 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/int-arithmetic.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/int-arithmetic.mir
@@ -23,7 +23,6 @@ body: |
%2:i32regbank(s32) = G_ADD %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: add_i64
alignment: 1
@@ -46,3 +45,273 @@ body: |
%2:i64regbank(s64) = G_ADD %0, %1
RETURN %2(s64), implicit-def $arguments
...
+
+---
+name: sub_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB_I32_:%[0-9]+]]:i32 = SUB_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[SUB_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_SUB %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sub_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB_I64_:%[0-9]+]]:i64 = SUB_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[SUB_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_SUB %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: mul_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL_I32_:%[0-9]+]]:i32 = MUL_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[MUL_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_MUL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: mul_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL_I64_:%[0-9]+]]:i64 = MUL_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[MUL_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_MUL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: udiv_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[DIV_U_I32_:%[0-9]+]]:i32 = DIV_U_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[DIV_U_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_UDIV %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: udiv_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[DIV_U_I64_:%[0-9]+]]:i64 = DIV_U_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[DIV_U_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_UDIV %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: sdiv_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sdiv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[DIV_S_I32_:%[0-9]+]]:i32 = DIV_S_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[DIV_S_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_SDIV %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sdiv_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sdiv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[DIV_S_I64_:%[0-9]+]]:i64 = DIV_S_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[DIV_S_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_SDIV %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: urem_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[REM_U_I32_:%[0-9]+]]:i32 = REM_U_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[REM_U_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_UREM %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: urem_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[REM_U_I64_:%[0-9]+]]:i64 = REM_U_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[REM_U_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_UREM %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: srem_i32
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: srem_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32 = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[REM_S_I32_:%[0-9]+]]:i32 = REM_S_I32 [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[REM_S_I32_]], implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32regbank(s32) = G_SREM %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: srem_i64
+alignment: 1
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: srem_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64 = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[REM_S_I64_:%[0-9]+]]:i64 = REM_S_I64 [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]], implicit-def dead $arguments
+ ; CHECK-NEXT: RETURN [[REM_S_I64_]], implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64regbank(s64) = G_SREM %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/add.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/add.mir
index 0d12b749e461e..8865e0e730f61 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/add.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/add.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
-# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=-sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,NO-SIGNEXT
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=+sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,SIGNEXT
---
name: add_i8_zext
@@ -35,16 +36,25 @@ body: |
bb.1.entry:
liveins: $arguments
- ; CHECK-LABEL: name: add_i8_sext
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
- ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ADD]], [[C]](s32)
- ; CHECK-NEXT: [[ASHR:%[0-9]+]]:i32(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ; NO-SIGNEXT-LABEL: name: add_i8_sext
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ADD]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:i32(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: add_i8_sext
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:i32(s32) = G_SEXT_INREG [[ADD]], 8
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
%2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s8) = G_TRUNC %2(s32)
%3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
@@ -113,16 +123,25 @@ body: |
bb.1.entry:
liveins: $arguments
- ; CHECK-LABEL: name: add_i16_sext
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
- ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ADD]], [[C]](s32)
- ; CHECK-NEXT: [[ASHR:%[0-9]+]]:i32(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ; NO-SIGNEXT-LABEL: name: add_i16_sext
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ADD]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:i32(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: add_i16_sext
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:i32(s32) = G_SEXT_INREG [[ADD]], 16
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
%2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s16) = G_TRUNC %2(s32)
%3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/and.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/and.mir
new file mode 100644
index 0000000000000..52c2de6715dd3
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/and.mir
@@ -0,0 +1,116 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: and_i1
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: and_i1
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[AND]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s1) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s1) = G_TRUNC %3(s32)
+ %4:_(s1) = G_AND %1, %0
+ %5:_(s32) = G_ANYEXT %4(s1)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: and_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: and_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[AND]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_AND %1, %0
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: and_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: and_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[AND]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_AND %1, %0
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: and_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: and_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[AND]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_AND %1, %0
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: and_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: and_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ARGUMENT_i64_1]], [[ARGUMENT_i64_]]
+ ; CHECK-NEXT: RETURN [[AND]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_AND %1, %0
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/anyext.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/anyext.mir
new file mode 100644
index 0000000000000..7380ad857cd9d
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/anyext.mir
@@ -0,0 +1,95 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: aext_i8_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: aext_i8_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: RETURN [[ARGUMENT_i32_]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_ANYEXT %0(s8)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: aext_i8_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: aext_i8_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:i32(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[ANYEXT]](s64), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s64) = G_ANYEXT %0(s8)
+ RETURN %2(s64), implicit-def $arguments
+...
+---
+name: aext_i16_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: aext_i16_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: RETURN [[ARGUMENT_i32_]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_ANYEXT %0(s16)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: aext_i16_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: aext_i16_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:i32(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[ANYEXT]](s64), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s64) = G_ANYEXT %0(s16)
+ RETURN %2(s64), implicit-def $arguments
+...
+---
+name: aext_i32_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: aext_i32_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:i32(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[ANYEXT]](s64), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s64) = G_ANYEXT %0(s32)
+ RETURN %1(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ashr.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ashr.mir
new file mode 100644
index 0000000000000..e38b3b87c9e8d
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ashr.mir
@@ -0,0 +1,331 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=-sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,NO-SIGNEXT
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=+sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,SIGNEXT
+
+---
+name: ashr_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: ashr_i8
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[ASHR]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR1]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: ashr_i8
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 8
+ ; SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[C]](s32)
+ ; SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %1:_(s8) = G_CONSTANT i8 5
+ %3:_(s8) = G_ASHR %0, %1
+ %4:_(s32) = G_ANYEXT %3(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: ashrv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: ashrv_i8
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; NO-SIGNEXT-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[ASHR]], [[AND]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR1]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: ashrv_i8
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 8
+ ; SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; SIGNEXT-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[AND]](s32)
+ ; SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_ASHR %0, %1
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: ashr_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: ashr_i16
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[ASHR]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR1]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: ashr_i16
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 16
+ ; SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[C]](s32)
+ ; SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %1:_(s16) = G_CONSTANT i16 13
+ %3:_(s16) = G_ASHR %0, %1
+ %4:_(s32) = G_ANYEXT %3(s16)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: ashrv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: ashrv_i16
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; NO-SIGNEXT-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[ASHR]], [[AND]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR1]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: ashrv_i16
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 16
+ ; SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; SIGNEXT-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SEXT_INREG]], [[AND]](s32)
+ ; SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_ASHR %0, %1
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: ashr_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CONSTANT i32 21
+ %2:_(s32) = G_ASHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ashrv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashrv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_ASHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ashr_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashr_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 21
+ %2:_(s32) = G_ASHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ashrv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashrv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = G_ASHR %0, %1
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ashr_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CONSTANT i64 37
+ %2:_(s64) = G_ASHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: ashrv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashrv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_ASHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: ashr_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashr_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 37
+ %2:_(s64) = G_ASHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: ashrv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ashrv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s64) = G_ASHR %0, %1
+ RETURN %3(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/constant.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/constant.mir
new file mode 100644
index 0000000000000..41b06f5c5c836
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/constant.mir
@@ -0,0 +1,145 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: const_i8_zext
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i8_zext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s8) = G_CONSTANT i8 255
+ %1:_(s32) = G_ZEXT %0(s8)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: const_i8_sext
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i8_sext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s8) = G_CONSTANT i8 255
+ %1:_(s32) = G_SEXT %0(s8)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: const_i8_aext
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i8_aext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s8) = G_CONSTANT i8 255
+ %1:_(s32) = G_ANYEXT %0(s8)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+
+---
+name: const_i16_zext
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i16_zext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s16) = G_CONSTANT i16 65535
+ %1:_(s32) = G_ZEXT %0(s16)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: const_i16_sext
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i16_sext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s16) = G_CONSTANT i16 65535
+ %1:_(s32) = G_SEXT %0(s16)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: const_i16_aext
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i16_aext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s16) = G_CONSTANT i16 65535
+ %1:_(s32) = G_ANYEXT %0(s16)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: const_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s32) = G_CONSTANT i32 4294967295
+ RETURN %0(s32), implicit-def $arguments
+...
+
+---
+name: const_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+ ; CHECK-NEXT: RETURN [[C]](s64), implicit-def $arguments
+ %0:_(s64) = G_CONSTANT i64 18446744073709551615
+ RETURN %0(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz.mir
new file mode 100644
index 0000000000000..39e1531194711
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz.mir
@@ -0,0 +1,152 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: ctlz_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[AND]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = nuw G_SUB [[CTLZ]], [[C1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:_(s8) = G_CTLZ %0
+ %3:_(s32) = G_ANYEXT %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[AND]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = nuw G_SUB [[CTLZ]], [[C1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:_(s16) = G_CTLZ %0
+ %3:_(s32) = G_ANYEXT %2(s16)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTLZ %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CTLZ %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTLZ %0
+ RETURN %1(s64), implicit-def $arguments
+
+...
+---
+name: ctlz_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CTLZ %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_i64_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i64_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s32) = G_CTLZ %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir
new file mode 100644
index 0000000000000..045706eb22c14
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir
@@ -0,0 +1,148 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: ctlz_zundef_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[SHL]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:_(s8) = G_CTLZ_ZERO_UNDEF %0
+ %3:_(s32) = G_ANYEXT %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_zundef_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[SHL]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:_(s16) = G_CTLZ_ZERO_UNDEF %0
+ %3:_(s32) = G_ANYEXT %2(s16)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_zundef_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_zundef_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CTLZ_ZERO_UNDEF %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_zundef_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s64), implicit-def $arguments
+
+...
+---
+name: ctlz_zundef_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CTLZ_ZERO_UNDEF %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ctlz_zundef_i64_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i64_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s32) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctpop.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctpop.mir
new file mode 100644
index 0000000000000..3dcbd10b40447
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctpop.mir
@@ -0,0 +1,148 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: ctpop_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:_(s8) = G_CTPOP %0
+ %3:_(s32) = G_ANYEXT %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ctpop_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:_(s16) = G_CTPOP %0
+ %3:_(s32) = G_ANYEXT %2(s16)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: ctpop_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTPOP %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
+---
+name: ctpop_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CTPOP %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ctpop_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s64) = G_CTPOP [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTPOP %0
+ RETURN %1(s64), implicit-def $arguments
+
+...
+---
+name: ctpop_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s64) = G_CTPOP [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTPOP]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CTPOP %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: ctpop_i64_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i64_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s64) = G_CTPOP [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTPOP]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s32) = G_CTPOP %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir
new file mode 100644
index 0000000000000..1d1d90b8420d6
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir
@@ -0,0 +1,148 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: cttz_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 256
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[OR]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:_(s8) = G_CTTZ %0
+ %3:_(s32) = G_ANYEXT %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: cttz_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65536
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[OR]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:_(s16) = G_CTTZ %0
+ %3:_(s32) = G_ANYEXT %2(s16)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: cttz_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTTZ %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
+---
+name: cttz_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CTTZ %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: cttz_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTTZ %0
+ RETURN %1(s64), implicit-def $arguments
+
+...
+---
+name: cttz_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CTTZ %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: cttz_i64_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i64_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s32) = G_CTTZ %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir
new file mode 100644
index 0000000000000..adb0cab5879d0
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir
@@ -0,0 +1,144 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: cttz_zundef_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:_(s8) = G_CTTZ_ZERO_UNDEF %0
+ %3:_(s32) = G_ANYEXT %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: cttz_zundef_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:_(s16) = G_CTTZ_ZERO_UNDEF %0
+ %3:_(s32) = G_ANYEXT %2(s16)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: cttz_zundef_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
+---
+name: cttz_zundef_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CTTZ_ZERO_UNDEF %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: cttz_zundef_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s64), implicit-def $arguments
+
+...
+---
+name: cttz_zundef_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CTTZ_ZERO_UNDEF %0
+ %2:_(s32) = G_ANYEXT %1(s8)
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: cttz_zundef_i64_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i64_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s32) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshl.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshl.mir
new file mode 100644
index 0000000000000..3aa32c39ee15f
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshl.mir
@@ -0,0 +1,393 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: fshl_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshl_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_CONSTANT i8 5
+ %5:_(s8) = G_FSHL %0, %1, %4(s8)
+ %6:_(s32) = G_ANYEXT %5(s8)
+ RETURN %6(s32), implicit-def $arguments
+
+...
+---
+name: fshlv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshlv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C3]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[C2]](s32)
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[LSHR]], [[C4]]
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[AND3]], [[AND1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR1]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %3:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %3(s32)
+ %4:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %4(s32)
+ %5:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s8) = G_TRUNC %5(s32)
+ %6:_(s8) = G_FSHL %0, %1, %2(s8)
+ %7:_(s32) = G_ANYEXT %6(s8)
+ RETURN %7(s32), implicit-def $arguments
+
+...
+---
+name: fshl_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshl_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_CONSTANT i16 13
+ %5:_(s16) = G_FSHL %0, %1, %4(s16)
+ %6:_(s32) = G_ANYEXT %5(s16)
+ RETURN %6(s32), implicit-def $arguments
+
+...
+---
+name: fshlv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshlv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C3]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[C2]](s32)
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[LSHR]], [[C4]]
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[AND3]], [[AND1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR1]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %3:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %3(s32)
+ %4:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %4(s32)
+ %5:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s16) = G_TRUNC %5(s32)
+ %6:_(s16) = G_FSHL %0, %1, %2(s16)
+ %7:_(s32) = G_ANYEXT %6(s16)
+ RETURN %7(s32), implicit-def $arguments
+
+...
+---
+name: fshl_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshl_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[C1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_CONSTANT i32 21
+ %3:_(s32) = G_FSHL %0, %1, %2(s32)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: fshlv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshlv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[C2]](s32)
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[LSHR]], [[AND1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR1]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %3:_(s32) = G_FSHL %0, %1, %2(s32)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: fshl_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshl_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[C1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s8) = G_CONSTANT i8 21
+ %3:_(s32) = G_FSHL %0, %1, %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: fshlv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshlv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[C2]](s32)
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[LSHR]], [[AND1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR1]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %3:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s8) = G_TRUNC %3(s32)
+ %4:_(s32) = G_FSHL %0, %1, %2(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: fshl_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshl_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 27
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[C1]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_CONSTANT i64 37
+ %3:_(s64) = G_FSHL %0, %1, %2(s64)
+ RETURN %3(s64), implicit-def $arguments
+
+...
+---
+name: fshlv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshlv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_2:%[0-9]+]]:i64(s64) = ARGUMENT_i64 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ARGUMENT_i64_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s64) = G_XOR [[ARGUMENT_i64_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[C2]](s64)
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s64) = G_LSHR [[LSHR]], [[AND1]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL]], [[LSHR1]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64(s64) = ARGUMENT_i64 2, implicit $arguments
+ %3:_(s64) = G_FSHL %0, %1, %2(s64)
+ RETURN %3(s64), implicit-def $arguments
+
+...
+---
+name: fshl_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshl_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 21
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 43
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[C2]], [[C3]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[AND1]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s8) = G_CONSTANT i8 21
+ %3:_(s64) = G_FSHL %0, %1, %2(s8)
+ RETURN %3(s64), implicit-def $arguments
+
+...
+---
+name: fshlv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshlv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 63
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[AND]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C2]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND2]](s64)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND [[C3]], [[C4]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[AND3]](s64)
+ ; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[AND1]](s32)
+ ; CHECK-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s64) = G_AND [[ANYEXT1]], [[C5]]
+ ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(s64) = G_LSHR [[LSHR]], [[AND4]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL]], [[LSHR1]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %3:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s8) = G_TRUNC %3(s32)
+ %4:_(s64) = G_FSHL %0, %1, %2(s8)
+ RETURN %4(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshr.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshr.mir
new file mode 100644
index 0000000000000..0437c51d310c9
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/fshr.mir
@@ -0,0 +1,389 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: fshr_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshr_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C1]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_CONSTANT i8 5
+ %5:_(s8) = G_FSHR %0, %1, %4(s8)
+ %6:_(s32) = G_ANYEXT %5(s8)
+ RETURN %6(s32), implicit-def $arguments
+
+...
+---
+name: fshrv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshrv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C2]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[SHL]], [[AND1]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C3]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[AND]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL1]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %3:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %3(s32)
+ %4:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %4(s32)
+ %5:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s8) = G_TRUNC %5(s32)
+ %6:_(s8) = G_FSHR %0, %1, %2(s8)
+ %7:_(s32) = G_ANYEXT %6(s8)
+ RETURN %7(s32), implicit-def $arguments
+
+...
+---
+name: fshr_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshr_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C1]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_CONSTANT i16 13
+ %5:_(s16) = G_FSHR %0, %1, %4(s16)
+ %6:_(s32) = G_ANYEXT %5(s16)
+ RETURN %6(s32), implicit-def $arguments
+
+...
+---
+name: fshrv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshrv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C2]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[SHL]], [[AND1]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C3]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[AND]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL1]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %3:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %3(s32)
+ %4:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %4(s32)
+ %5:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s16) = G_TRUNC %5(s32)
+ %6:_(s16) = G_FSHR %0, %1, %2(s16)
+ %7:_(s32) = G_ANYEXT %6(s16)
+ RETURN %7(s32), implicit-def $arguments
+
+...
+---
+name: fshr_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C1]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[C]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_CONSTANT i32 21
+ %3:_(s32) = G_FSHR %0, %1, %2(s32)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: fshrv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshrv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C2]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[SHL]], [[AND1]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[AND]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL1]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %3:_(s32) = G_FSHR %0, %1, %2(s32)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: fshr_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshr_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C1]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[C]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s8) = G_CONSTANT i8 21
+ %3:_(s32) = G_FSHR %0, %1, %2(s8)
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: fshrv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshrv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C2]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[SHL]], [[AND1]](s32)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_1]], [[AND]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL1]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %3:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s8) = G_TRUNC %3(s32)
+ %4:_(s32) = G_FSHR %0, %1, %2(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: fshr_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 27
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[C1]](s64)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[C]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_CONSTANT i64 37
+ %3:_(s64) = G_FSHR %0, %1, %2(s64)
+ RETURN %3(s64), implicit-def $arguments
+
+...
+---
+name: fshrv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshrv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_2:%[0-9]+]]:i64(s64) = ARGUMENT_i64 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ARGUMENT_i64_2]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s64) = G_XOR [[ARGUMENT_i64_2]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[C2]](s64)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[SHL]], [[AND1]](s64)
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[AND]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL1]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:i64(s64) = ARGUMENT_i64 2, implicit $arguments
+ %3:_(s64) = G_FSHR %0, %1, %2(s64)
+ RETURN %3(s64), implicit-def $arguments
+
+...
+---
+name: fshr_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshr_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 43
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 21
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[C2]], [[C3]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[AND1]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s8) = G_CONSTANT i8 21
+ %3:_(s64) = G_FSHR %0, %1, %2(s8)
+ RETURN %3(s64), implicit-def $arguments
+
+...
+---
+name: fshrv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: fshrv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 63
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_]], [[C1]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND [[C2]], [[C3]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND2]](s64)
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[AND1]](s32)
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C4]]
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[SHL]], [[AND3]](s64)
+ ; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[AND]](s32)
+ ; CHECK-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s64) = G_AND [[ANYEXT1]], [[C5]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_1]], [[AND4]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = disjoint G_OR [[SHL1]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %3:i32(s32) = ARGUMENT_i32 2, implicit $arguments
+ %2:_(s8) = G_TRUNC %3(s32)
+ %4:_(s64) = G_FSHR %0, %1, %2(s8)
+ RETURN %4(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/implicit_def.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/implicit_def.mir
new file mode 100644
index 0000000000000..4b6685214a963
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/implicit_def.mir
@@ -0,0 +1,72 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: implicit_def_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_def_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]](s32), implicit-def $arguments
+ %0:_(s8) = G_IMPLICIT_DEF
+ %1:_(s32) = G_ANYEXT %0(s8)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: implicit_def_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_def_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]](s32), implicit-def $arguments
+ %0:_(s16) = G_IMPLICIT_DEF
+ %1:_(s32) = G_ANYEXT %0(s16)
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: implicit_def_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_def_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]](s32), implicit-def $arguments
+ %0:_(s32) = G_IMPLICIT_DEF
+ RETURN %0(s32), implicit-def $arguments
+...
+
+---
+name: implicit_def_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_def_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]](s64), implicit-def $arguments
+ %0:_(s64) = G_IMPLICIT_DEF
+ RETURN %0(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/lshr.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/lshr.mir
new file mode 100644
index 0000000000000..f8150c9cfd7a4
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/lshr.mir
@@ -0,0 +1,286 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: lshr_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %1:_(s8) = G_CONSTANT i8 5
+ %3:_(s8) = G_LSHR %0, %1
+ %4:_(s32) = G_ANYEXT %3(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: lshrv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshrv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[AND1]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_LSHR %0, %1
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: lshr_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %1:_(s16) = G_CONSTANT i16 13
+ %3:_(s16) = G_LSHR %0, %1
+ %4:_(s32) = G_ANYEXT %3(s16)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: lshrv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshrv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[AND1]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_LSHR %0, %1
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: lshr_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CONSTANT i32 21
+ %2:_(s32) = G_LSHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: lshrv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshrv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_LSHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: lshr_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 21
+ %2:_(s32) = G_LSHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: lshrv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshrv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = G_LSHR %0, %1
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: lshr_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[LSHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CONSTANT i64 37
+ %2:_(s64) = G_LSHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: lshrv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshrv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[LSHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_LSHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: lshr_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[LSHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 37
+ %2:_(s64) = G_LSHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: lshrv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshrv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[LSHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s64) = G_LSHR %0, %1
+ RETURN %3(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/mul.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/mul.mir
new file mode 100644
index 0000000000000..537d8f9fcf52d
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/mul.mir
@@ -0,0 +1,91 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: mul_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[MUL]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_MUL %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: mul_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[MUL]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_MUL %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: mul_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[MUL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_MUL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: mul_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[MUL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_MUL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/or.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/or.mir
new file mode 100644
index 0000000000000..d86bd04d2e455
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/or.mir
@@ -0,0 +1,117 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: or_i1
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i1
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s1) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s1) = G_TRUNC %3(s32)
+ %4:_(s1) = G_OR %1, %0
+ %5:_(s32) = G_ANYEXT %4(s1)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: or_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_OR %1, %0
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: or_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_OR %1, %0
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: or_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_OR %1, %0
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: or_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[ARGUMENT_i64_1]], [[ARGUMENT_i64_]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_OR %1, %0
+ RETURN %2(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotl.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotl.mir
new file mode 100644
index 0000000000000..82c1bcf76ae5b
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotl.mir
@@ -0,0 +1,303 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+
+---
+name: rotl_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %1:_(s8) = G_CONSTANT i8 5
+ %3:_(s8) = G_ROTL %0, %1
+ %4:_(s32) = G_ANYEXT %3(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: rotlv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotlv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]], [[C1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[AND1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_ROTL %0, %1
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: rotl_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %1:_(s16) = G_CONSTANT i16 13
+ %3:_(s16) = G_ROTL %0, %1
+ %4:_(s32) = G_ANYEXT %3(s16)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: rotlv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotlv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]], [[C1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[AND1]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[SHL]], [[LSHR]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_ROTL %0, %1
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: rotl_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ROTL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CONSTANT i32 21
+ %2:_(s32) = G_ROTL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: rotlv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotlv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[ROTL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_ROTL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: rotl_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ROTL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 21
+ %2:_(s32) = G_ROTL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: rotlv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotlv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[ROTL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = G_ROTL %0, %1
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: rotl_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s64) = G_ROTL [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[ROTL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CONSTANT i64 37
+ %2:_(s64) = G_ROTL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: rotlv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotlv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s64) = G_ROTL [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[ROTL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_ROTL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: rotl_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s64) = G_ROTL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[ROTL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 37
+ %2:_(s64) = G_ROTL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: rotlv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotlv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s64) = G_ROTL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[ROTL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s64) = G_ROTL %0, %1
+ RETURN %3(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotr.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotr.mir
new file mode 100644
index 0000000000000..e8fc7e5db324e
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/rotr.mir
@@ -0,0 +1,303 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+
+---
+name: rotr_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C2]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %1:_(s8) = G_CONSTANT i8 5
+ %3:_(s8) = G_ROTR %0, %1
+ %4:_(s32) = G_ANYEXT %3(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: rotrv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotrv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[AND]](s32)
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[SUB]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND2]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_ROTR %0, %1
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: rotr_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C1]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C2]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %1:_(s16) = G_CONSTANT i16 13
+ %3:_(s16) = G_ROTR %0, %1
+ %4:_(s32) = G_ANYEXT %3(s16)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: rotrv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotrv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C2]]
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[AND]](s32)
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[SUB]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND2]](s32)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = disjoint G_OR [[LSHR]], [[SHL]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_ROTR %0, %1
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: rotr_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ROTR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CONSTANT i32 21
+ %2:_(s32) = G_ROTR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: rotrv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotrv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[ROTR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_ROTR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: rotr_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ROTR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 21
+ %2:_(s32) = G_ROTR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: rotrv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotrv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[ROTR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = G_ROTR %0, %1
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: rotr_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s64) = G_ROTR [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[ROTR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CONSTANT i64 37
+ %2:_(s64) = G_ROTR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: rotrv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotrv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s64) = G_ROTR [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[ROTR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_ROTR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: rotr_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s64) = G_ROTR [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[ROTR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 37
+ %2:_(s64) = G_ROTR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: rotrv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotrv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s64) = G_ROTR [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[ROTR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s64) = G_ROTR %0, %1
+ RETURN %3(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sdiv.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sdiv.mir
new file mode 100644
index 0000000000000..e7d3581e1c1b7
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sdiv.mir
@@ -0,0 +1,126 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=-sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,NO-SIGNEXT
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=+sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,SIGNEXT
+
+---
+name: sdiv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sdiv_i8
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[ASHR]], [[ASHR1]]
+ ; NO-SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SDIV]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sdiv_i8
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 8
+ ; SIGNEXT-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_1]], 8
+ ; SIGNEXT-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SDIV]](s32)
+ ; SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_SDIV %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: sdiv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sdiv_i16
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[ASHR]], [[ASHR1]]
+ ; NO-SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SDIV]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sdiv_i16
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 16
+ ; SIGNEXT-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_1]], 16
+ ; SIGNEXT-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SDIV]](s32)
+ ; SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_SDIV %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: sdiv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sdiv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[SDIV]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SDIV %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sdiv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sdiv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[SDIV]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SDIV %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext.mir
new file mode 100644
index 0000000000000..6b443b1f91e82
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext.mir
@@ -0,0 +1,138 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=-sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,NO-SIGNEXT
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=+sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,SIGNEXT
+
+---
+name: sext_i8_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_i8_i32
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:i32(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_i8_i32
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:i32(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 8
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_SEXT %0(s8)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sext_i8_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_i8_i64
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ANYEXT]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:i32(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_i8_i64
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:i32(s64) = G_SEXT_INREG [[ANYEXT]], 8
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s64) = G_SEXT %0(s8)
+ RETURN %2(s64), implicit-def $arguments
+...
+---
+name: sext_i16_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_i16_i32
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:i32(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_i16_i32
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:i32(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 16
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_SEXT %0(s16)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sext_i16_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_i16_i64
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ANYEXT]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:i32(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_i16_i64
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:i32(s64) = G_SEXT_INREG [[ANYEXT]], 16
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s64) = G_SEXT %0(s16)
+ RETURN %2(s64), implicit-def $arguments
+...
+---
+name: sext_i32_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_i32_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT:%[0-9]+]]:i32(s64) = G_SEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[SEXT]](s64), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s64) = G_SEXT %0(s32)
+ RETURN %1(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext_inreg.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext_inreg.mir
new file mode 100644
index 0000000000000..2d5daf7b906f3
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sext_inreg.mir
@@ -0,0 +1,181 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=-sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,NO-SIGNEXT
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=+sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,SIGNEXT
+
+---
+name: sext_inreg_i1_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i1_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL %1, [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_SEXT_INREG %1(s32), 1
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: sext_inreg_i8_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_inreg_i8_i32
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL %1, [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_inreg_i8_i32
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[SEXT_INREG]], 8
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_SEXT_INREG %1(s32), 8
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: sext_inreg_i16_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_inreg_i16_i32
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL %1, [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_inreg_i16_i32
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[SEXT_INREG]], 16
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_SEXT_INREG %1(s32), 16
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i1_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i1_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL %1, [[C]](s64)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %1(s64), 1
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: sext_inreg_i8_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_inreg_i8_i64
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL %1, [[C]](s64)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_inreg_i8_i64
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[SEXT_INREG]], 8
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %1(s64), 8
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: sext_inreg_i16_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_inreg_i16_i64
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL %1, [[C]](s64)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_inreg_i16_i64
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[SEXT_INREG]], 16
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %1(s64), 16
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i32_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: sext_inreg_i32_i64
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL %1, [[C]](s64)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; NO-SIGNEXT-NEXT: RETURN [[ASHR]](s64), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: sext_inreg_i32_i64
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[SEXT_INREG]], 32
+ ; SIGNEXT-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %1(s64), 32
+ RETURN %1(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/shl.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/shl.mir
new file mode 100644
index 0000000000000..25c75c551a1e7
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/shl.mir
@@ -0,0 +1,278 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: shl_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shl_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %1:_(s8) = G_CONSTANT i8 5
+ %3:_(s8) = G_SHL %0, %1
+ %4:_(s32) = G_ANYEXT %3(s8)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: shlv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shlv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_SHL %0, %1
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: shl_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shl_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %1:_(s16) = G_CONSTANT i16 13
+ %3:_(s16) = G_SHL %0, %1
+ %4:_(s32) = G_ANYEXT %3(s16)
+ RETURN %4(s32), implicit-def $arguments
+
+...
+---
+name: shlv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shlv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_SHL %0, %1
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: shl_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shl_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CONSTANT i32 21
+ %2:_(s32) = G_SHL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: shlv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shlv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SHL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: shl_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shl_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 21
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 21
+ %2:_(s32) = G_SHL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: shlv_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shlv_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[AND]](s32)
+ ; CHECK-NEXT: RETURN [[SHL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = G_SHL %0, %1
+ RETURN %3(s32), implicit-def $arguments
+
+...
+---
+name: shl_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shl_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[SHL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CONSTANT i64 37
+ %2:_(s64) = G_SHL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: shlv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shlv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[SHL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SHL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: shl_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shl_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[C]], [[C1]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[SHL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s8) = G_CONSTANT i8 37
+ %2:_(s64) = G_SHL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+
+...
+---
+name: shlv_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: shlv_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ARGUMENT_i64_]], [[AND]](s64)
+ ; CHECK-NEXT: RETURN [[SHL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %2:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %2(s32)
+ %3:_(s64) = G_SHL %0, %1
+ RETURN %3(s64), implicit-def $arguments
+
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/srem.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/srem.mir
new file mode 100644
index 0000000000000..e6d9d2c5bad2d
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/srem.mir
@@ -0,0 +1,126 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=-sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,NO-SIGNEXT
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -mattr=+sign-ext -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,SIGNEXT
+
+---
+name: srem_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: srem_i8
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; NO-SIGNEXT-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[ASHR]], [[ASHR1]]
+ ; NO-SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SREM]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: srem_i8
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 8
+ ; SIGNEXT-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_1]], 8
+ ; SIGNEXT-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SREM]](s32)
+ ; SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_SREM %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: srem_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; NO-SIGNEXT-LABEL: name: srem_i16
+ ; NO-SIGNEXT: liveins: $arguments
+ ; NO-SIGNEXT-NEXT: {{ $}}
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; NO-SIGNEXT-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; NO-SIGNEXT-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; NO-SIGNEXT-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; NO-SIGNEXT-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[ASHR]], [[ASHR1]]
+ ; NO-SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SREM]](s32)
+ ; NO-SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ ;
+ ; SIGNEXT-LABEL: name: srem_i16
+ ; SIGNEXT: liveins: $arguments
+ ; SIGNEXT-NEXT: {{ $}}
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; SIGNEXT-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; SIGNEXT-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 16
+ ; SIGNEXT-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[ARGUMENT_i32_1]], 16
+ ; SIGNEXT-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; SIGNEXT-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SREM]](s32)
+ ; SIGNEXT-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_SREM %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: srem_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: srem_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[SREM]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SREM %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: srem_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: srem_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[SREM]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SREM %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sub.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sub.mir
new file mode 100644
index 0000000000000..97770cb6280cb
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/sub.mir
@@ -0,0 +1,91 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: sub_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SUB]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_SUB %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: sub_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[SUB]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_SUB %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: sub_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SUB %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sub_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SUB %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/trunc.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/trunc.mir
new file mode 100644
index 0000000000000..c9dfd3175e6d6
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/trunc.mir
@@ -0,0 +1,95 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: trunc_i32_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc_i32_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: RETURN [[ARGUMENT_i32_]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_ANYEXT %0(s8)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: trunc_i32_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc_i32_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: RETURN [[ARGUMENT_i32_]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_ANYEXT %0(s16)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: trunc_i64_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc_i64_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:i32(s32) = G_TRUNC [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %1:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s64)
+ %2:i32(s32) = G_ANYEXT %0(s8)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: trunc_i64_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc_i64_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:i32(s32) = G_TRUNC [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %1:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s64)
+ %2:i32(s32) = G_ANYEXT %0(s16)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: trunc_i64_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc_i64_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %1:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %0:_(s32) = G_TRUNC %1(s64)
+ RETURN %0(s32), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/udiv.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/udiv.mir
new file mode 100644
index 0000000000000..9d547bf0a110a
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/udiv.mir
@@ -0,0 +1,99 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: udiv_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[UDIV]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_UDIV %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: udiv_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[UDIV]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_UDIV %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: udiv_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[UDIV]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_UDIV %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: udiv_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[UDIV]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_UDIV %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/urem.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/urem.mir
new file mode 100644
index 0000000000000..068023509eb07
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/urem.mir
@@ -0,0 +1,99 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: urem_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[AND]], [[AND1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[UREM]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_UREM %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: urem_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_1]], [[C1]]
+ ; CHECK-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[AND]], [[AND1]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:i32(s32) = COPY [[UREM]](s32)
+ ; CHECK-NEXT: RETURN [[COPY]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_UREM %0, %1
+ %5:i32(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+...
+---
+name: urem_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[UREM]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_UREM %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: urem_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[UREM]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_UREM %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/xor.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/xor.mir
new file mode 100644
index 0000000000000..1bc7ace2b3e7f
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/xor.mir
@@ -0,0 +1,116 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: xor_i1
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i1
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[XOR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s1) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s1) = G_TRUNC %3(s32)
+ %4:_(s1) = G_XOR %1, %0
+ %5:_(s32) = G_ANYEXT %4(s1)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: xor_i8
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[XOR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8) = G_XOR %1, %0
+ %5:_(s32) = G_ANYEXT %4(s8)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: xor_i16
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[XOR]](s32), implicit-def $arguments
+ %2:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16) = G_XOR %1, %0
+ %5:_(s32) = G_ANYEXT %4(s16)
+ RETURN %5(s32), implicit-def $arguments
+
+...
+---
+name: xor_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ARGUMENT_i32_1]], [[ARGUMENT_i32_]]
+ ; CHECK-NEXT: RETURN [[XOR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_XOR %1, %0
+ RETURN %2(s32), implicit-def $arguments
+
+...
+---
+name: xor_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s64) = G_XOR [[ARGUMENT_i64_1]], [[ARGUMENT_i64_]]
+ ; CHECK-NEXT: RETURN [[XOR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_XOR %1, %0
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/zext.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/zext.mir
new file mode 100644
index 0000000000000..84ee4cc9ac3e1
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/zext.mir
@@ -0,0 +1,103 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: zext_i8_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext_i8_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:i32(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: RETURN [[AND]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_ZEXT %0(s8)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: zext_i8_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext_i8_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:i32(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: RETURN [[AND]](s64), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s8) = G_TRUNC %1(s32)
+ %2:i32(s64) = G_ZEXT %0(s8)
+ RETURN %2(s64), implicit-def $arguments
+...
+---
+name: zext_i16_i32
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext_i16_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:i32(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: RETURN [[AND]](s32), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s32) = G_ZEXT %0(s16)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: zext_i16_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext_i16_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:i32(s64) = G_AND [[ANYEXT]], [[C]]
+ ; CHECK-NEXT: RETURN [[AND]](s64), implicit-def $arguments
+ %1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %0:_(s16) = G_TRUNC %1(s32)
+ %2:i32(s64) = G_ZEXT %0(s16)
+ RETURN %2(s64), implicit-def $arguments
+...
+---
+name: zext_i32_i64
+alignment: 1
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext_i32_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:i32(s64) = G_ZEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[ZEXT]](s64), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s64) = G_ZEXT %0(s32)
+ RETURN %1(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir
index 157ef5b9034c2..185ab2d550084 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir
@@ -22,7 +22,6 @@ body: |
%2:_(s32) = G_AND %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: and_i64
alignment: 1
@@ -45,6 +44,92 @@ body: |
RETURN %2(s64), implicit-def $arguments
...
+---
+name: or_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:i32regbank(s32) = G_OR [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[OR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_OR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: or_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: or_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:i64regbank(s64) = G_OR [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[OR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_OR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: xor_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:i32regbank(s32) = G_XOR [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[XOR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_XOR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: xor_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: xor_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:i64regbank(s64) = G_XOR [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[XOR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_XOR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
---
name: shl_i32
alignment: 1
@@ -66,7 +151,6 @@ body: |
%2:_(s32) = G_SHL %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: shl_i64
alignment: 1
@@ -110,7 +194,6 @@ body: |
%2:_(s32) = G_ASHR %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: ashr_i64
alignment: 1
@@ -132,3 +215,328 @@ body: |
%2:_(s64) = G_ASHR %0, %1
RETURN %2(s64), implicit-def $arguments
...
+
+---
+name: lshr_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:i32regbank(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:i32regbank(s32) = G_LSHR [[ARGUMENT_i32_]], [[C]](s32)
+ ; CHECK-NEXT: RETURN [[LSHR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CONSTANT i32 5
+ %2:_(s32) = G_LSHR %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: lshr_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: lshr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:i64regbank(s64) = G_CONSTANT i64 37
+ ; CHECK-NEXT: [[LSHR:%[0-9]+]]:i64regbank(s64) = G_LSHR [[ARGUMENT_i64_]], [[C]](s64)
+ ; CHECK-NEXT: RETURN [[LSHR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CONSTANT i64 37
+ %2:_(s64) = G_LSHR %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: ctlz_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:i32regbank(s32) = G_CTLZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTLZ %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: ctlz_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:i64regbank(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTLZ %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: ctlz_zundef_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:i32regbank(s32) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: ctlz_zundef_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctlz_zundef_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:i64regbank(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTLZ_ZERO_UNDEF %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: cttz_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:i32regbank(s32) = G_CTTZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTTZ %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: cttz_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:i64regbank(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTTZ %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: cttz_zundef_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:i32regbank(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: cttz_zundef_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: cttz_zundef_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:i64regbank(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTTZ_ZERO_UNDEF %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+
+---
+name: ctpop_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:i32regbank(s32) = G_CTPOP [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_CTPOP %0
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: ctpop_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: ctpop_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[CTPOP:%[0-9]+]]:i64regbank(s64) = G_CTPOP [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTPOP]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_CTPOP %0
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: rotl_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:i32regbank(s32) = G_ROTL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[ROTL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_ROTL %0, %1(s32)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: rotl_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotl_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTL:%[0-9]+]]:i64regbank(s64) = G_ROTL [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[ROTL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_ROTL %0, %1(s64)
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: rotr_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:i32regbank(s32) = G_ROTR [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]](s32)
+ ; CHECK-NEXT: RETURN [[ROTR]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_ROTR %0, %1(s32)
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: rotr_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: rotr_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[ROTR:%[0-9]+]]:i64regbank(s64) = G_ROTR [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]](s64)
+ ; CHECK-NEXT: RETURN [[ROTR]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_ROTR %0, %1(s64)
+ RETURN %2(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/consts.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/consts.mir
new file mode 100644
index 0000000000000..3cf45bbcf3702
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/consts.mir
@@ -0,0 +1,72 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: const_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:i32regbank(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: RETURN [[C]](s32), implicit-def $arguments
+ %0:_(s32) = G_CONSTANT i32 0
+ RETURN %0(s32), implicit-def $arguments
+...
+---
+name: const_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: const_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:i64regbank(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: RETURN [[C]](s64), implicit-def $arguments
+ %0:_(s64) = G_CONSTANT i64 0
+ RETURN %0(s64), implicit-def $arguments
+...
+
+---
+name: implicit_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:i32regbank(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]](s32), implicit-def $arguments
+ %0:_(s32) = G_IMPLICIT_DEF
+ RETURN %0(s32), implicit-def $arguments
+...
+---
+name: implicit_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: implicit_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:i64regbank(s64) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: RETURN [[DEF]](s64), implicit-def $arguments
+ %0:_(s64) = G_IMPLICIT_DEF
+ RETURN %0(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/ext-trunc.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/ext-trunc.mir
new file mode 100644
index 0000000000000..a95bb61143547
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/ext-trunc.mir
@@ -0,0 +1,177 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=wasm32-unknown-unknown -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: anyext
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: anyext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:i64regbank(s64) = G_ANYEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[ANYEXT]](s64), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s64) = G_ANYEXT %0
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: sext
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT:%[0-9]+]]:i64regbank(s64) = G_SEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[SEXT]](s64), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s64) = G_SEXT %0
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: zext
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: zext
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:i64regbank(s64) = G_ZEXT [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[ZEXT]](s64), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s64) = G_ZEXT %0
+ RETURN %1(s64), implicit-def $arguments
+...
+---
+name: trunc
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: trunc
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:i32regbank(s32) = G_TRUNC [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s32) = G_TRUNC %0
+ RETURN %1(s32), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i32_8
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i32_8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:i32regbank(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 8
+ ; CHECK-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_SEXT_INREG %0, 8
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: sext_inreg_i64_8
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i64_8
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:i64regbank(s64) = G_SEXT_INREG [[ARGUMENT_i64_]], 8
+ ; CHECK-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %0, 8
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i32_16
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i32_16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:i32regbank(s32) = G_SEXT_INREG [[ARGUMENT_i32_]], 16
+ ; CHECK-NEXT: RETURN [[SEXT_INREG]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:_(s32) = G_SEXT_INREG %0, 16
+ RETURN %1(s32), implicit-def $arguments
+...
+---
+name: sext_inreg_i64_16
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i64_16
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:i64regbank(s64) = G_SEXT_INREG [[ARGUMENT_i64_]], 16
+ ; CHECK-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %0, 16
+ RETURN %1(s64), implicit-def $arguments
+...
+
+---
+name: sext_inreg_i64_32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sext_inreg_i64_32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:i64regbank(s64) = G_SEXT_INREG [[ARGUMENT_i64_]], 32
+ ; CHECK-NEXT: RETURN [[SEXT_INREG]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:_(s64) = G_SEXT_INREG %0, 32
+ RETURN %1(s64), implicit-def $arguments
+...
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/int-arithmetic.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/int-arithmetic.mir
index 1a2515d4b9abe..a2118b9744051 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/int-arithmetic.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/int-arithmetic.mir
@@ -22,7 +22,6 @@ body: |
%2:_(s32) = G_ADD %0, %1
RETURN %2(s32), implicit-def $arguments
...
-
---
name: add_i64
alignment: 1
@@ -44,3 +43,261 @@ body: |
%2:_(s64) = G_ADD %0, %1
RETURN %2(s64), implicit-def $arguments
...
+
+---
+name: sub_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:i32regbank(s32) = G_SUB [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SUB %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sub_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sub_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:i64regbank(s64) = G_SUB [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SUB %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: mul_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:i32regbank(s32) = G_MUL [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[MUL]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_MUL %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: mul_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: mul_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:i64regbank(s64) = G_MUL [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[MUL]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_MUL %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: udiv_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:i32regbank(s32) = G_UDIV [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[UDIV]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_UDIV %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: udiv_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: udiv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:i64regbank(s64) = G_UDIV [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[UDIV]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_UDIV %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: sdiv_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sdiv_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SDIV:%[0-9]+]]:i32regbank(s32) = G_SDIV [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[SDIV]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SDIV %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: sdiv_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: sdiv_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SDIV:%[0-9]+]]:i64regbank(s64) = G_SDIV [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[SDIV]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SDIV %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: urem_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[UREM:%[0-9]+]]:i32regbank(s32) = G_UREM [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[UREM]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_UREM %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: urem_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: urem_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[UREM:%[0-9]+]]:i64regbank(s64) = G_UREM [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[UREM]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_UREM %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
+
+---
+name: srem_i32
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: srem_i32
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ ; CHECK-NEXT: [[SREM:%[0-9]+]]:i32regbank(s32) = G_SREM [[ARGUMENT_i32_]], [[ARGUMENT_i32_1]]
+ ; CHECK-NEXT: RETURN [[SREM]](s32), implicit-def $arguments
+ %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
+ %1:i32(s32) = ARGUMENT_i32 1, implicit $arguments
+ %2:_(s32) = G_SREM %0, %1
+ RETURN %2(s32), implicit-def $arguments
+...
+---
+name: srem_i64
+alignment: 1
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $arguments
+
+ ; CHECK-LABEL: name: srem_i64
+ ; CHECK: liveins: $arguments
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ ; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ ; CHECK-NEXT: [[SREM:%[0-9]+]]:i64regbank(s64) = G_SREM [[ARGUMENT_i64_]], [[ARGUMENT_i64_1]]
+ ; CHECK-NEXT: RETURN [[SREM]](s64), implicit-def $arguments
+ %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
+ %1:i64(s64) = ARGUMENT_i64 1, implicit $arguments
+ %2:_(s64) = G_SREM %0, %1
+ RETURN %2(s64), implicit-def $arguments
+...
>From 579a3c5a1127c26774ac84dfdfd30164de7e4c7a Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Fri, 3 Apr 2026 10:33:55 -0700
Subject: [PATCH 2/3] Address review comments
---
.../GISel/WebAssemblyInstructionSelector.cpp | 31 +------------
.../GISel/WebAssemblyLegalizerInfo.cpp | 2 +-
.../WebAssembly/WebAssemblyRegisterInfo.cpp | 46 +++++++++++++++++++
.../WebAssembly/WebAssemblyRegisterInfo.h | 3 ++
4 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp
index 7359156ccf60c..19b4cffa334bc 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp
@@ -84,30 +84,6 @@ WebAssemblyInstructionSelector::WebAssemblyInstructionSelector(
{
}
-static const TargetRegisterClass &getRegClassForBank(const RegisterBank &RB) {
- switch (RB.getID()) {
- case WebAssembly::I32RegBankID:
- return WebAssembly::I32RegClass;
- case WebAssembly::I64RegBankID:
- return WebAssembly::I64RegClass;
- case WebAssembly::F32RegBankID:
- return WebAssembly::F32RegClass;
- case WebAssembly::F64RegBankID:
- return WebAssembly::F64RegClass;
- case WebAssembly::EXNREFRegBankID:
- return WebAssembly::EXNREFRegClass;
- case WebAssembly::EXTERNREFRegBankID:
- return WebAssembly::EXTERNREFRegClass;
- case WebAssembly::FUNCREFRegBankID:
- return WebAssembly::FUNCREFRegClass;
- case WebAssembly::V128RegBankID:
- return WebAssembly::V128RegClass;
- default:
- reportFatalInternalError(
- "Found unexpected RegisterBank in `getRegClassForBank`");
- }
-}
-
bool WebAssemblyInstructionSelector::select(MachineInstr &I) {
MachineBasicBlock &MBB = *I.getParent();
MachineFunction &MF = *MBB.getParent();
@@ -125,18 +101,15 @@ bool WebAssemblyInstructionSelector::select(MachineInstr &I) {
switch (I.getOpcode()) {
case G_IMPLICIT_DEF: {
const Register DefReg = I.getOperand(0).getReg();
- const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(DefReg);
const TargetRegisterClass *DefRC =
- dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
+ TRI.getConstrainedRegClassForOperand(I.getOperand(0), MRI);
if (!DefRC) {
- const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
- DefRC = &getRegClassForBank(RB);
+ return false;
}
I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
-
return RBI.constrainGenericRegister(DefReg, *DefRC, MRI) != nullptr;
}
default:
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
index 0b9bbc1a6853a..ab19ad9499048 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
@@ -65,8 +65,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
.clampScalar(1, s64, s64);
getActionDefinitionsBuilder(G_SEXT_INREG)
- .clampScalar(0, s32, s64)
.customFor(ST.hasSignExt(), {s32, s64})
+ .clampScalar(0, s32, s64)
.lower();
getLegacyLegalizerInfo().computeTables();
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
index ebb5f555df67a..4b4f07bd782ad 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "WebAssemblyRegisterInfo.h"
+#include "GISel/WebAssemblyRegisterBankInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyFrameLowering.h"
#include "WebAssemblyInstrInfo.h"
@@ -154,3 +155,48 @@ WebAssemblyRegisterInfo::getPointerRegClass(unsigned Kind) const {
return TT.getArch() == Triple::wasm64 ? &WebAssembly::I64RegClass
: &WebAssembly::I32RegClass;
}
+
+static const TargetRegisterClass &getRegClassForBank(const RegisterBank &RB) {
+ switch (RB.getID()) {
+ case WebAssembly::I32RegBankID:
+ return WebAssembly::I32RegClass;
+ case WebAssembly::I64RegBankID:
+ return WebAssembly::I64RegClass;
+ case WebAssembly::F32RegBankID:
+ return WebAssembly::F32RegClass;
+ case WebAssembly::F64RegBankID:
+ return WebAssembly::F64RegClass;
+ case WebAssembly::EXNREFRegBankID:
+ return WebAssembly::EXNREFRegClass;
+ case WebAssembly::EXTERNREFRegBankID:
+ return WebAssembly::EXTERNREFRegClass;
+ case WebAssembly::FUNCREFRegBankID:
+ return WebAssembly::FUNCREFRegClass;
+ case WebAssembly::V128RegBankID:
+ return WebAssembly::V128RegClass;
+ default:
+ llvm_unreachable("Found unexpected RegisterBank in `getRegClassForBank`");
+ }
+}
+
+const TargetRegisterClass *
+WebAssemblyRegisterInfo::getConstrainedRegClassForOperand(
+ const MachineOperand &MO, const MachineRegisterInfo &MRI) const {
+ assert(MO.isReg());
+
+ const RegClassOrRegBank &RegClassOrBank =
+ MRI.getRegClassOrRegBank(MO.getReg());
+
+ if (RegClassOrBank.isNull())
+ return nullptr;
+
+ const TargetRegisterClass *DefRC =
+ dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
+
+ if (!DefRC) {
+ const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
+ DefRC = &getRegClassForBank(RB);
+ }
+
+ return DefRC;
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
index 3a73ff6b1b3b0..5b4293b9ec590 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
@@ -45,6 +45,9 @@ class WebAssemblyRegisterInfo final : public WebAssemblyGenRegisterInfo {
getPointerRegClass(unsigned Kind = 0) const override;
// This does not apply to wasm.
const uint32_t *getNoPreservedMask() const override { return nullptr; }
+
+ const TargetRegisterClass *getConstrainedRegClassForOperand(
+ const MachineOperand &MO, const MachineRegisterInfo &MRI) const override;
};
} // end namespace llvm
>From c49ab5144c596e445a162ba5794a6302b973b290 Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Fri, 3 Apr 2026 11:21:42 -0700
Subject: [PATCH 3/3] Lower `G_[CTLZ|CTTZ]_ZERO_UNDEF` instead of legal
---
.../GISel/WebAssemblyLegalizerInfo.cpp | 6 +-
.../WebAssembly/WebAssemblyInstrInteger.td | 8 --
.../GlobalISel/instruction-select/bitwise.mir | 82 -------------------
.../GlobalISel/legalizer/ctlz_zero_undef.mir | 40 +++++----
.../WebAssembly/GlobalISel/legalizer/cttz.mir | 8 +-
.../GlobalISel/legalizer/cttz_zero_undef.mir | 32 ++++----
.../GlobalISel/regbankselect/bitwise.mir | 79 ------------------
7 files changed, 48 insertions(+), 207 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
index ab19ad9499048..293ba88605354 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "WebAssemblyLegalizerInfo.h"
+#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblySubtarget.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
@@ -40,13 +41,14 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
.clampScalar(0, s32, s64)
.scalarSameSizeAs(1, 0);
- getActionDefinitionsBuilder(
- {G_CTLZ, G_CTLZ_ZERO_UNDEF, G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTPOP})
+ getActionDefinitionsBuilder({G_CTLZ, G_CTTZ, G_CTPOP})
.legalFor({{s32, s32}, {s64, s64}})
.widenScalarToNextPow2(1)
.clampScalar(1, s32, s64)
.scalarSameSizeAs(0, 1);
+ getActionDefinitionsBuilder({G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF}).lower();
+
getActionDefinitionsBuilder({G_ROTL, G_ROTR})
.legalFor({{s32, s32}, {s64, s64}})
.scalarSameSizeAs(1, 0)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
index 99ca22e21f70b..991507e883f28 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
@@ -82,18 +82,10 @@ defm LE_U : ComparisonInt<SETULE, "le_u", 0x4d, 0x58>;
defm GE_S : ComparisonInt<SETGE, "ge_s", 0x4e, 0x59>;
defm GE_U : ComparisonInt<SETUGE, "ge_u", 0x4f, 0x5a>;
-
defm CLZ : UnaryInt<ctlz, "clz ", 0x67, 0x79>;
-def : Pat<(ctlz_zero_undef I32:$src), (CLZ_I32 I32:$src)>;
-def : Pat<(ctlz_zero_undef I64:$src), (CLZ_I64 I64:$src)>;
-
defm CTZ : UnaryInt<cttz, "ctz ", 0x68, 0x7a>;
-def : Pat<(cttz_zero_undef I32:$src), (CTZ_I32 I32:$src)>;
-def : Pat<(cttz_zero_undef I64:$src), (CTZ_I64 I64:$src)>;
-
defm POPCNT : UnaryInt<ctpop, "popcnt", 0x69, 0x7b>;
-
defm EQZ_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
[(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
"i32.eqz \t$dst, $src", "i32.eqz", 0x45>;
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir
index 1a5943259b521..2af53ff71ce2d 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instruction-select/bitwise.mir
@@ -312,47 +312,6 @@ body: |
RETURN %1(s64), implicit-def $arguments
...
----
-name: ctlz_zundef_i32
-alignment: 1
-legalized: true
-regBankSelected: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: ctlz_zundef_i32
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CLZ_I32_:%[0-9]+]]:i32 = CLZ_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
- ; CHECK-NEXT: RETURN [[CLZ_I32_]], implicit-def $arguments
- %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- %1:i32regbank(s32) = G_CTLZ_ZERO_UNDEF %0
- RETURN %1(s32), implicit-def $arguments
-...
----
-name: ctlz_zundef_i64
-alignment: 1
-legalized: true
-regBankSelected: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: ctlz_zundef_i64
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CLZ_I64_:%[0-9]+]]:i64 = CLZ_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
- ; CHECK-NEXT: RETURN [[CLZ_I64_]], implicit-def $arguments
- %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- %1:i64regbank(s64) = G_CTLZ_ZERO_UNDEF %0
- RETURN %1(s64), implicit-def $arguments
-...
-
---
name: cttz_i32
alignment: 1
@@ -394,47 +353,6 @@ body: |
RETURN %1(s64), implicit-def $arguments
...
----
-name: cttz_zundef_i32
-alignment: 1
-legalized: true
-regBankSelected: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: cttz_zundef_i32
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32 = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTZ_I32_:%[0-9]+]]:i32 = CTZ_I32 [[ARGUMENT_i32_]], implicit-def dead $arguments
- ; CHECK-NEXT: RETURN [[CTZ_I32_]], implicit-def $arguments
- %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- %1:i32regbank(s32) = G_CTTZ_ZERO_UNDEF %0
- RETURN %1(s32), implicit-def $arguments
-...
----
-name: cttz_zundef_i64
-alignment: 1
-legalized: true
-regBankSelected: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: cttz_zundef_i64
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64 = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTZ_I64_:%[0-9]+]]:i64 = CTZ_I64 [[ARGUMENT_i64_]], implicit-def dead $arguments
- ; CHECK-NEXT: RETURN [[CTZ_I64_]], implicit-def $arguments
- %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- %1:i64regbank(s64) = G_CTTZ_ZERO_UNDEF %0
- RETURN %1(s64), implicit-def $arguments
-...
-
---
name: ctpop_i32
alignment: 1
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir
index 045706eb22c14..e00396d20b7e3 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/ctlz_zero_undef.mir
@@ -13,10 +13,12 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[SHL]](s32)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[AND]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = nuw G_SUB [[CTLZ]], [[C1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s32), implicit-def $arguments
%1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s8) = G_TRUNC %1(s32)
%2:_(s8) = G_CTLZ_ZERO_UNDEF %0
@@ -36,10 +38,12 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ARGUMENT_i32_]], [[C]](s32)
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[SHL]](s32)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[AND]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = nuw G_SUB [[CTLZ]], [[C1]]
+ ; CHECK-NEXT: RETURN [[SUB]](s32), implicit-def $arguments
%1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s16) = G_TRUNC %1(s32)
%2:_(s16) = G_CTLZ_ZERO_UNDEF %0
@@ -59,8 +63,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s32), implicit-def $arguments
%0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%1:_(s32) = G_CTLZ_ZERO_UNDEF %0
RETURN %1(s32), implicit-def $arguments
@@ -78,8 +82,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s32), implicit-def $arguments
%0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%1:_(s8) = G_CTLZ_ZERO_UNDEF %0
%2:_(s32) = G_ANYEXT %1(s8)
@@ -98,8 +102,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s64), implicit-def $arguments
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTLZ]](s64), implicit-def $arguments
%0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
%1:_(s64) = G_CTLZ_ZERO_UNDEF %0
RETURN %1(s64), implicit-def $arguments
@@ -117,8 +121,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ]](s64)
; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
%0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
%1:_(s8) = G_CTLZ_ZERO_UNDEF %0
@@ -138,8 +142,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTLZ]](s64)
; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
%0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
%1:_(s32) = G_CTLZ_ZERO_UNDEF %0
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir
index 1d1d90b8420d6..2feeb10b39c38 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz.mir
@@ -15,8 +15,8 @@ body: |
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 256
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_]], [[C]]
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[OR]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[OR]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
%1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s8) = G_TRUNC %1(s32)
%2:_(s8) = G_CTTZ %0
@@ -38,8 +38,8 @@ body: |
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65536
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_]], [[C]]
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[OR]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[OR]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
%1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s16) = G_TRUNC %1(s32)
%2:_(s16) = G_CTTZ %0
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir
index adb0cab5879d0..b76234b48fe10 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/legalizer/cttz_zero_undef.mir
@@ -13,8 +13,10 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 256
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[OR]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
%1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s8) = G_TRUNC %1(s32)
%2:_(s8) = G_CTTZ_ZERO_UNDEF %0
@@ -34,8 +36,10 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65536
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[ARGUMENT_i32_]], [[C]]
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[OR]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
%1:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%0:_(s16) = G_TRUNC %1(s32)
%2:_(s16) = G_CTTZ_ZERO_UNDEF %0
@@ -55,8 +59,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
%0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%1:_(s32) = G_CTTZ_ZERO_UNDEF %0
RETURN %1(s32), implicit-def $arguments
@@ -74,8 +78,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[ARGUMENT_i32_]](s32)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s32), implicit-def $arguments
%0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
%1:_(s8) = G_CTTZ_ZERO_UNDEF %0
%2:_(s32) = G_ANYEXT %1(s8)
@@ -94,8 +98,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s64), implicit-def $arguments
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: RETURN [[CTTZ]](s64), implicit-def $arguments
%0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
%1:_(s64) = G_CTTZ_ZERO_UNDEF %0
RETURN %1(s64), implicit-def $arguments
@@ -113,8 +117,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ]](s64)
; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
%0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
%1:_(s8) = G_CTTZ_ZERO_UNDEF %0
@@ -134,8 +138,8 @@ body: |
; CHECK: liveins: $arguments
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ_ZERO_UNDEF]](s64)
+ ; CHECK-NEXT: [[CTTZ:%[0-9]+]]:_(s64) = G_CTTZ [[ARGUMENT_i64_]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[CTTZ]](s64)
; CHECK-NEXT: RETURN [[TRUNC]](s32), implicit-def $arguments
%0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
%1:_(s32) = G_CTTZ_ZERO_UNDEF %0
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir
index 185ab2d550084..9657732d43aaf 100644
--- a/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/regbankselect/bitwise.mir
@@ -298,45 +298,6 @@ body: |
RETURN %1(s64), implicit-def $arguments
...
----
-name: ctlz_zundef_i32
-alignment: 1
-legalized: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: ctlz_zundef_i32
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:i32regbank(s32) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s32), implicit-def $arguments
- %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- %1:_(s32) = G_CTLZ_ZERO_UNDEF %0
- RETURN %1(s32), implicit-def $arguments
-...
----
-name: ctlz_zundef_i64
-alignment: 1
-legalized: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: ctlz_zundef_i64
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTLZ_ZERO_UNDEF:%[0-9]+]]:i64regbank(s64) = G_CTLZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: RETURN [[CTLZ_ZERO_UNDEF]](s64), implicit-def $arguments
- %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- %1:_(s64) = G_CTLZ_ZERO_UNDEF %0
- RETURN %1(s64), implicit-def $arguments
-...
-
---
name: cttz_i32
alignment: 1
@@ -376,46 +337,6 @@ body: |
RETURN %1(s64), implicit-def $arguments
...
----
-name: cttz_zundef_i32
-alignment: 1
-legalized: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: cttz_zundef_i32
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:i32regbank(s32) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i32_]](s32)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s32), implicit-def $arguments
- %0:i32(s32) = ARGUMENT_i32 0, implicit $arguments
- %1:_(s32) = G_CTTZ_ZERO_UNDEF %0
- RETURN %1(s32), implicit-def $arguments
-...
----
-name: cttz_zundef_i64
-alignment: 1
-legalized: true
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $arguments
-
- ; CHECK-LABEL: name: cttz_zundef_i64
- ; CHECK: liveins: $arguments
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- ; CHECK-NEXT: [[CTTZ_ZERO_UNDEF:%[0-9]+]]:i64regbank(s64) = G_CTTZ_ZERO_UNDEF [[ARGUMENT_i64_]](s64)
- ; CHECK-NEXT: RETURN [[CTTZ_ZERO_UNDEF]](s64), implicit-def $arguments
- %0:i64(s64) = ARGUMENT_i64 0, implicit $arguments
- %1:_(s64) = G_CTTZ_ZERO_UNDEF %0
- RETURN %1(s64), implicit-def $arguments
-...
-
-
---
name: ctpop_i32
alignment: 1
More information about the llvm-commits
mailing list