LLVM 24.0.0git
WebAssemblyLegalizerInfo.cpp
Go to the documentation of this file.
1//===- WebAssemblyLegalizerInfo.cpp ------------------------------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the Machinelegalizer class for
10/// WebAssembly.
11//===----------------------------------------------------------------------===//
12
18
19#define DEBUG_TYPE "wasm-legalinfo"
20
21using namespace llvm;
22using namespace LegalizeActions;
23using namespace LegalityPredicates;
24
26 const WebAssemblySubtarget &ST) {
27 using namespace TargetOpcode;
28
29 const LLT i32 = LLT::integer(32);
30 const LLT i64 = LLT::integer(64);
31
32 const LLT f32 = LLT::floatIEEE(32);
33 const LLT f64 = LLT::floatIEEE(64);
34
35 const LLT s32 = LLT::scalar(32);
36 const LLT s64 = LLT::scalar(64);
37
38 getActionDefinitionsBuilder(G_IMPLICIT_DEF)
39 .legalFor({i32, i64, f32, f64})
40 .widenScalarToNextPow2(0)
41 .clampScalar(0, s32, s64);
42
43 getActionDefinitionsBuilder({G_CONSTANT, G_ADD, G_SUB, G_MUL, G_UDIV, G_SDIV,
44 G_UREM, G_SREM, G_AND, G_OR, G_XOR})
45 .legalFor({i32, i64})
46 .widenScalarToNextPow2(0)
47 .clampScalar(0, s32, s64);
48
49 getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
50 .legalFor({{i32, i32}, {i64, i64}})
51 .widenScalarToNextPow2(0)
52 .clampScalar(0, s32, s64)
53 .scalarSameSizeAs(1, 0);
54
55 getActionDefinitionsBuilder({G_CTLZ, G_CTTZ, G_CTPOP})
56 .legalFor({{i32, i32}, {i64, i64}})
57 .widenScalarToNextPow2(1)
58 .clampScalar(1, s32, s64)
59 .scalarSameSizeAs(0, 1);
60
61 getActionDefinitionsBuilder({G_CTLZ_ZERO_POISON, G_CTTZ_ZERO_POISON}).lower();
62
63 getActionDefinitionsBuilder({G_ROTL, G_ROTR})
64 .legalFor({{i32, i32}, {i64, i64}})
65 .scalarSameSizeAs(1, 0)
66 .lower();
67
68 getActionDefinitionsBuilder({G_FSHL, G_FSHR}).lower();
69
71 .legalForCartesianProduct({i32}, {i32, i64})
72 .widenScalarToNextPow2(1)
73 .clampScalar(0, s32, s32)
74 .clampScalar(1, s32, s64);
75
76 getActionDefinitionsBuilder({G_UMIN, G_UMAX, G_SMIN, G_SMAX}).lower();
77
78 getActionDefinitionsBuilder({G_SCMP, G_UCMP}).lower();
79
80 getActionDefinitionsBuilder({G_ANYEXT, G_SEXT, G_ZEXT})
81 .legalFor({{i64, i32}})
82 .clampScalar(0, s64, s64)
83 .clampScalar(1, s32, s32);
84
86 .legalFor({{i32, i64}})
87 .clampScalar(0, s32, s32)
88 .clampScalar(1, s64, s64);
89
90 {
91 LegalizeRuleSet &Builder = getActionDefinitionsBuilder(G_SEXT_INREG);
92
93 if (ST.hasSignExt())
94 Builder.legalIf(
95 all(typeInSet(0, {i32, i64}),
97 all(typeIs(0, i64), immIs(0, 32)))));
98
99 Builder.clampScalar(0, s32, s64).lower();
100 }
101
102 getActionDefinitionsBuilder({G_FCONSTANT, G_FABS, G_FNEG, G_FCEIL, G_FFLOOR,
103 G_INTRINSIC_TRUNC, G_FNEARBYINT, G_FRINT,
104 G_INTRINSIC_ROUNDEVEN, G_FSQRT, G_FADD, G_FSUB,
105 G_FMUL, G_FDIV})
106 .legalFor({f32, f64})
107 .minScalar(0, s32);
108
109 getActionDefinitionsBuilder(G_FCOPYSIGN)
110 .legalFor({f32, f64})
111 .minScalar(0, s32)
112 .scalarSameSizeAs(1, 0);
113
115 .legalFor({{f64, f32}})
116 .clampScalar(0, s64, s64)
117 .clampScalar(1, s32, s32);
118
120 .legalFor({{f32, f64}})
121 .clampScalar(0, s32, s32)
122 .clampScalar(1, s64, s64);
123
125 .legalFor({{i32, f32}, {f32, i32}, {i64, f64}, {f64, i64}})
126 .clampScalar(0, s32, s64)
127 .clampScalar(1, s32, s64);
128
129 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
130 .legalForCartesianProduct({i32, i64}, {f32, f64})
131 .clampScalar(0, s32, s64)
132 .minScalar(1, s32);
133
134 // TODO: once comparison ops are in place
135 /*if (ST.hasNontrappingFPToInt()) {
136 getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
137 .legalForCartesianProduct({i32, i64}, {f32, f64})
138 .clampScalar(0, s32, s64)
139 .minScalar(1, s32);
140 } else {
141 getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
142 .lowerForCartesianProduct({i32, i64}, {f32, f64})
143 .clampScalar(0, s32, s64)
144 .minScalar(1, s32);
145 }*/
146
147 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
148 .legalForCartesianProduct({f32, f64}, {i32, i64})
149 .minScalar(0, s32)
150 .clampScalar(1, s32, s64);
151
153 .legalForCartesianProduct({i32, i64, f32, f64}, {i32})
154 .widenScalarToNextPow2(0)
155 .clampScalar(0, s32, s64)
156 .clampScalar(1, s32, s32);
157}
158
161 LostDebugLocObserver &LocObserver) const {
162 switch (MI.getOpcode()) {
163 default:
164 break;
165 }
166 return false;
167}
IRTranslator LLVM IR MI
Interface for Targets to specify which operations they can successfully select and how the others sho...
This file declares the targeting of the Machinelegalizer class for WebAssembly.
This file provides WebAssembly-specific target descriptions.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static LLT integer(unsigned SizeInBits)
static LLT floatIEEE(unsigned SizeInBits)
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
Representation of each machine instruction.
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override
Called for instructions with the Custom LegalizationAction.
WebAssemblyLegalizerInfo(const WebAssemblySubtarget &ST)
LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LLVM_ABI LegalityPredicate immIs(unsigned ImmIdx, int64_t Imm)
True iff the immediate at the given index has the specified value.
Predicate any(Predicate P0, Predicate P1)
True iff P0 or P1 are true.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified type.
LLVM_ABI LegalityPredicate immInSet(unsigned ImmIdx, std::initializer_list< int64_t > ImmsInit)
True iff the immediate at the given index has one of the specified values.
Invariant opcodes: All instruction sets have these as their low opcodes.
This is an optimization pass for GlobalISel generic memory operations.