MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
+ unsigned WideSize = WideTy.getSizeInBits();
switch (MI.getOpcode()) {
default:
return UnableToLegalize;
// Perform operation at larger width (any extension is fine here, high bits
// don't affect the result) and then truncate the result back to the
// original type.
- unsigned WideSize = WideTy.getSizeInBits();
MIRBuilder.setInstr(MI);
MI.eraseFromParent();
return Legalized;
}
+ case TargetOpcode::G_CONSTANT: {
+ MIRBuilder.setInstr(MI);
+ unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
+ MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
+ MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
+ MI.eraseFromParent();
+ return Legalized;
+ }
}
}
[&](LLT Ty) -> LLT { return Ty.halfScalarSize(); });
}
case WidenScalar: {
- return findLegalType(Opcode, Ty,
- [&](LLT Ty) -> LLT { return Ty.doubleScalarSize(); });
+ return findLegalType(Opcode, Ty, [&](LLT Ty) -> LLT {
+ return Ty.getSizeInBits() < 8 ? LLT::scalar(8) : Ty.doubleScalarSize();
+ });
}
case FewerElements: {
return findLegalType(Opcode, Ty,
AArch64MachineLegalizer::AArch64MachineLegalizer() {
using namespace TargetOpcode;
+ const LLT s1 = LLT::scalar(1);
const LLT s8 = LLT::scalar(8);
const LLT s16 = LLT::scalar(16);
const LLT s32 = LLT::scalar(32);
for (auto Ty : {s32, s64})
setAction(MemOp, Ty, Legal);
+ for (auto Ty : {s32, s64}) {
+ setAction(TargetOpcode::G_CONSTANT, Ty, Legal);
+ setAction(TargetOpcode::G_FCONSTANT, Ty, Legal);
+ }
+
+ for (auto Ty : {s1, s8, s16})
+ setAction(TargetOpcode::G_CONSTANT, Ty, WidenScalar);
+
setAction(G_BR, LLT::unsized(), Legal);
--- /dev/null
+# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - 2>&1 | FileCheck %s
+
+--- |
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64-apple-ios"
+ define void @test_constant() {
+ entry:
+ ret void
+ }
+ define void @test_fconstant() {
+ entry:
+ ret void
+ }
+...
+
+---
+name: test_constant
+isSSA: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+ - { id: 4, class: _ }
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_constant
+ ; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 0
+ ; CHECK: %0(1) = G_TRUNC s1 [[TMP]]
+ ; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 42
+ ; CHECK: %1(8) = G_TRUNC s8 [[TMP]]
+ ; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 65535
+ ; CHECK: %2(16) = G_TRUNC s16 [[TMP]]
+ ; CHECK: %3(32) = G_CONSTANT s32 -1
+ ; CHECK: %4(64) = G_CONSTANT s64 1
+
+ %0(1) = G_CONSTANT s1 0
+ %1(8) = G_CONSTANT s8 42
+ %2(16) = G_CONSTANT s16 65535
+ %3(32) = G_CONSTANT s32 -1
+ %4(64) = G_CONSTANT s64 1
+...
+
+---
+name: test_fconstant
+isSSA: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_fconstant
+ ; CHECK: %0(32) = G_FCONSTANT s32 float 1.000000e+00
+ ; CHECK: %1(64) = G_FCONSTANT s64 double 2.000000e+00
+
+ %0(32) = G_FCONSTANT s32 float 1.0
+ %1(64) = G_FCONSTANT s64 double 2.0
+...