Skip to content

Commit

Permalink
GlobalISel: Restrict narrow scalar for fptoui/fptosi results
Browse files Browse the repository at this point in the history
This practically only works for the f16 case AMDGPU uses, not wider
types.

Fixes bug 49710 by failing legalization.
  • Loading branch information
arsenm committed Apr 20, 2021
1 parent 8fbe04f commit 83a25a1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ class LegalizerHelper {
LegalizeResult narrowScalarAddSub(MachineInstr &MI, unsigned TypeIdx,
LLT NarrowTy);
LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
LegalizeResult narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);

Expand Down
44 changes: 28 additions & 16 deletions llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1216,22 +1216,9 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
Observer.changedInstr(MI);
return Legalized;
}
case TargetOpcode::G_FPTOUI: {
if (TypeIdx != 0)
return UnableToLegalize;
Observer.changingInstr(MI);
narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_ZEXT);
Observer.changedInstr(MI);
return Legalized;
}
case TargetOpcode::G_FPTOSI: {
if (TypeIdx != 0)
return UnableToLegalize;
Observer.changingInstr(MI);
narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_SEXT);
Observer.changedInstr(MI);
return Legalized;
}
case TargetOpcode::G_FPTOUI:
case TargetOpcode::G_FPTOSI:
return narrowScalarFPTOI(MI, TypeIdx, NarrowTy);
case TargetOpcode::G_FPEXT:
if (TypeIdx != 0)
return UnableToLegalize;
Expand Down Expand Up @@ -4846,6 +4833,31 @@ LegalizerHelper::narrowScalarMul(MachineInstr &MI, LLT NarrowTy) {
return Legalized;
}

LegalizerHelper::LegalizeResult
LegalizerHelper::narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx,
LLT NarrowTy) {
if (TypeIdx != 0)
return UnableToLegalize;

bool IsSigned = MI.getOpcode() == TargetOpcode::G_FPTOSI;

Register Src = MI.getOperand(1).getReg();
LLT SrcTy = MRI.getType(Src);

// If all finite floats fit into the narrowed integer type, we can just swap
// out the result type. This is practically only useful for conversions from
// half to at least 16-bits, so just handle the one case.
if (SrcTy.getScalarType() != LLT::scalar(16) ||
NarrowTy.getScalarSizeInBits() < (IsSigned ? 17 : 16))
return UnableToLegalize;

Observer.changingInstr(MI);
narrowScalarDst(MI, NarrowTy, 0,
IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT);
Observer.changedInstr(MI);
return Legalized;
}

LegalizerHelper::LegalizeResult
LegalizerHelper::narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx,
LLT NarrowTy) {
Expand Down
28 changes: 28 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/legalize-fptoi.mir
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,31 @@ body: |
%1:_(<4 x s32>) = G_FPTOSI %0
$q0 = COPY %1
...

---
name: test_fptoui_s128_s32
body: |
bb.0:
liveins: $w0
; CHECK-LABEL: name: test_fptoui_s128_s32
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK: [[FPTOUI:%[0-9]+]]:_(s128) = G_FPTOUI [[COPY]](s32)
; CHECK: $q0 = COPY [[FPTOUI]](s128)
%0:_(s32) = COPY $w0
%1:_(s128) = G_FPTOUI %0
$q0 = COPY %1
...

---
name: test_fptosi_s128_s32
body: |
bb.0:
liveins: $w0
; CHECK-LABEL: name: test_fptosi_s128_s32
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK: [[FPTOSI:%[0-9]+]]:_(s128) = G_FPTOSI [[COPY]](s32)
; CHECK: $q0 = COPY [[FPTOSI]](s128)
%0:_(s32) = COPY $w0
%1:_(s128) = G_FPTOSI %0
$q0 = COPY %1
...

0 comments on commit 83a25a1

Please sign in to comment.