Skip to content

Commit 3e46aee

Browse files
committed
Fix #12.
1 parent efc2b24 commit 3e46aee

File tree

1 file changed

+58
-15
lines changed

1 file changed

+58
-15
lines changed

Diff for: llvm/lib/Target/Z80/GISel/Z80LegalizerInfo.cpp

+58-15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Z80MachineFunctionInfo.h"
1616
#include "Z80Subtarget.h"
1717
#include "Z80TargetMachine.h"
18+
#include "llvm/ADT/STLExtras.h"
1819
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
1920
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
2021
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
@@ -26,10 +27,49 @@ using namespace TargetOpcode;
2627
using namespace LegalizeActions;
2728
using namespace MIPatternMatch;
2829

30+
static LegalityPredicate typeNotInSet(unsigned TypeIdx,
31+
std::initializer_list<LLT> TypesInit) {
32+
using namespace LegalityPredicates;
33+
SmallVector<LLT, 8> Types = TypesInit;
34+
return [=](const LegalityQuery &Query) {
35+
return !is_contained(Types, Query.Types[TypeIdx]);
36+
};
37+
}
38+
39+
static LegalityPredicate scalarNotInSet(unsigned TypeIdx,
40+
std::initializer_list<LLT> Types) {
41+
using namespace LegalityPredicates;
42+
return all(isScalar(TypeIdx), typeNotInSet(TypeIdx, Types));
43+
}
44+
45+
static LegalizeRuleSet &
46+
widenScalarToNextOrNarrowToLast(LegalizeRuleSet &Builder, unsigned TypeIdx,
47+
std::initializer_list<LLT> TypesInit) {
48+
using namespace LegalityPredicates;
49+
SmallVector<LLT, 8> Types = TypesInit;
50+
assert(!Types.empty() && is_sorted(Types, [](LLT Ty1, LLT Ty2) {
51+
return Ty1.getSizeInBits() < Ty2.getSizeInBits();
52+
}) && "Expected type set to be not empty and sorted by width.");
53+
return Builder.maxScalar(TypeIdx, Types.back())
54+
.widenScalarIf(
55+
scalarNotInSet(TypeIdx, TypesInit), [=](const LegalityQuery &Query) {
56+
LLT QueryTy = Query.Types[TypeIdx];
57+
for (LLT Ty : reverse(Types))
58+
if (QueryTy.getSizeInBits() < Ty.getSizeInBits())
59+
return std::make_pair(TypeIdx, Ty);
60+
llvm_unreachable("Scalar wider than last already handled.");
61+
});
62+
}
63+
2964
Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
3065
const Z80TargetMachine &TM)
3166
: Subtarget(STI), TM(TM) {
67+
using namespace LegalizeActions;
68+
using namespace LegalityPredicates;
69+
using namespace LegalizeMutations;
70+
3271
bool Is24Bit = Subtarget.is24Bit();
72+
LegalityPredicate pred24Bit = [=](const LegalityQuery &) { return Is24Bit; };
3373

3474
std::array<LLT, 5> p;
3575
for (int AddrSpace = 0; AddrSpace != p.size(); ++AddrSpace)
@@ -39,6 +79,7 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
3979
LLT s16 = LLT::scalar(16);
4080
LLT s24 = LLT::scalar(24);
4181
LLT s32 = LLT::scalar(32);
82+
LLT s48 = LLT::scalar(48);
4283
LLT s64 = LLT::scalar(64);
4384
LLT sMax = Is24Bit ? s24 : s16;
4485
LLT sOther = Is24Bit ? s16 : s24;
@@ -57,6 +98,9 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
5798
auto LegalLibcallScalars16 = {s8, s16, s32, s64};
5899
auto LegalLibcallScalars =
59100
Is24Bit ? LegalLibcallScalars24 : LegalLibcallScalars16;
101+
auto LibcallScalars24 = {s8, s16, s24, s32, s48, s64};
102+
auto LibcallScalars16 = {s8, s16, s32, s64};
103+
auto LibcallScalars = Is24Bit ? LibcallScalars24 : LibcallScalars16;
60104
auto NotMax24 = {s8, s16}, NotMax16 = {s8};
61105
auto NotMax = Is24Bit ? NotMax24 : NotMax16;
62106
auto NotMin24 = {s16, s24}, NotMin16 = {s16};
@@ -159,13 +203,11 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
159203
.legalForCartesianProduct(LegalScalars, {s1})
160204
.clampScalar(0, s8, sMax);
161205

162-
{
163-
auto &&Mul = getActionDefinitionsBuilder(G_MUL);
164-
if (Subtarget.hasZ180Ops())
165-
Mul.legalFor({s8});
166-
Mul.libcallFor(LegalLibcallScalars)
167-
.clampScalar(0, s8, s32);
168-
}
206+
getActionDefinitionsBuilder(G_MUL)
207+
.legalIf(all(pred24Bit, typeIs(0, s8)))
208+
.libcallFor(LegalLibcallScalars)
209+
.narrowScalarIf(all(pred24Bit, typeIs(0, s48)), changeTo(0, s24))
210+
.clampScalar(0, s8, s32);
169211

170212
getActionDefinitionsBuilder({G_SDIV, G_UDIV, G_SREM, G_UREM})
171213
.libcallFor(LegalLibcallScalars)
@@ -176,10 +218,12 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
176218
.customFor(LegalLibcallScalars)
177219
.clampScalar(0, s8, s32);
178220

179-
getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
180-
.customForCartesianProduct(LegalLibcallScalars, {s8})
181-
.clampScalar(1, s8, s8)
182-
.clampScalar(0, s8, s64);
221+
widenScalarToNextOrNarrowToLast(
222+
getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
223+
.customForCartesianProduct(LegalLibcallScalars, {s8})
224+
.clampScalar(1, s8, s8)
225+
.narrowScalarIf(all(pred24Bit, typeIs(0, s48)), changeTo(0, s24)),
226+
0, LibcallScalars);
183227

184228
getActionDefinitionsBuilder({G_FSHL, G_FSHR, G_ROTR, G_ROTL, G_UMULO,
185229
G_UMULFIX, G_SMULFIX, G_SMULFIXSAT, G_UMULFIXSAT,
@@ -260,11 +304,10 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
260304
.customForCartesianProduct({s1}, {s32, s64})
261305
.clampScalar(1, s8, s64);
262306

263-
getActionDefinitionsBuilder(G_FCMP)
264-
.customForCartesianProduct({s1}, {s32, s64});
307+
getActionDefinitionsBuilder(G_FCMP).customForCartesianProduct({s1},
308+
{s32, s64});
265309

266-
getActionDefinitionsBuilder(G_BRCOND)
267-
.legalFor({s1});
310+
getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
268311

269312
getActionDefinitionsBuilder(G_BRJT)
270313
.legalForCartesianProduct({p[0]}, LegalScalars)

0 commit comments

Comments
 (0)