mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[Hexagon] Handle widening of truncation's operand with legal result
Failing example: v8i8 = truncate v8i32. v8i8 is legal, but v8i32 was widened to HVX. Make sure that v8i8 does not get altered (even if it's changed to another legal type).
This commit is contained in:
parent
94da56feaf
commit
77adca5920
@ -487,6 +487,7 @@ private:
|
||||
findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
|
||||
const override;
|
||||
|
||||
bool shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const;
|
||||
bool isHvxOperation(SDNode *N, SelectionDAG &DAG) const;
|
||||
SDValue LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const;
|
||||
void LowerHvxOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
||||
|
@ -1939,16 +1939,36 @@ HexagonTargetLowering::WidenHvxTruncate(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDValue Op0 = Op.getOperand(0);
|
||||
MVT ResTy = ty(Op);
|
||||
MVT OpTy = ty(Op0);
|
||||
|
||||
// .-res, op-> Scalar Illegal HVX
|
||||
// Scalar ok extract(widen) -
|
||||
// Illegal - widen widen
|
||||
// HVX - - ok
|
||||
|
||||
if (Subtarget.isHVXVectorType(OpTy))
|
||||
return DAG.getNode(HexagonISD::VPACKL, dl, getWideTy(ResTy), Op0);
|
||||
|
||||
assert(!isTypeLegal(OpTy) && "HVX-widening a truncate of scalar?");
|
||||
|
||||
MVT WideOpTy = getWideTy(OpTy);
|
||||
SmallVector<SDValue, 4> Concats = {Op0};
|
||||
for (int i = 0, e = getFactor(OpTy) - 1; i != e; ++i)
|
||||
Concats.push_back(DAG.getUNDEF(OpTy));
|
||||
|
||||
SDValue Cat = DAG.getNode(ISD::CONCAT_VECTORS, dl, WideOpTy, Concats);
|
||||
return DAG.getNode(HexagonISD::VPACKL, dl, getWideTy(ResTy), Cat);
|
||||
SDValue V = DAG.getNode(HexagonISD::VPACKL, dl, getWideTy(ResTy), Cat);
|
||||
// If the original result wasn't legal and was supposed to be widened,
|
||||
// we're done.
|
||||
if (shouldWidenToHvx(ResTy, DAG))
|
||||
return V;
|
||||
|
||||
// The original result type wasn't meant to be widened to HVX, so
|
||||
// leave it as it is. Standard legalization should be able to deal
|
||||
// with it (since now it's a result of a target-idendependent ISD
|
||||
// node).
|
||||
assert(ResTy.isVector());
|
||||
return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ResTy,
|
||||
{V, getZero(dl, MVT::i32, DAG)});
|
||||
}
|
||||
|
||||
SDValue
|
||||
@ -2029,11 +2049,15 @@ HexagonTargetLowering::LowerHvxOperationWrapper(SDNode *N,
|
||||
SDValue Op(N, 0);
|
||||
|
||||
switch (Opc) {
|
||||
case ISD::TRUNCATE: {
|
||||
assert(shouldWidenToHvx(ty(Op.getOperand(0)), DAG) && "Not widening?");
|
||||
SDValue T = WidenHvxTruncate(Op, DAG);
|
||||
Results.push_back(T);
|
||||
break;
|
||||
}
|
||||
case ISD::STORE: {
|
||||
assert(
|
||||
getPreferredHvxVectorAction(ty(cast<StoreSDNode>(N)->getValue())) ==
|
||||
TargetLoweringBase::TypeWidenVector &&
|
||||
"Not widening?");
|
||||
assert(shouldWidenToHvx(ty(cast<StoreSDNode>(N)->getValue()), DAG) &&
|
||||
"Not widening?");
|
||||
SDValue Store = WidenHvxStore(SDValue(N, 0), DAG);
|
||||
Results.push_back(Store);
|
||||
break;
|
||||
@ -2061,12 +2085,12 @@ HexagonTargetLowering::ReplaceHvxNodeResults(SDNode *N,
|
||||
unsigned Opc = N->getOpcode();
|
||||
SDValue Op(N, 0);
|
||||
switch (Opc) {
|
||||
case ISD::TRUNCATE:
|
||||
if (!Subtarget.isHVXVectorType(ty(Op), false)) {
|
||||
SDValue T = WidenHvxTruncate(Op, DAG);
|
||||
Results.push_back(T);
|
||||
}
|
||||
case ISD::TRUNCATE: {
|
||||
assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
|
||||
SDValue T = WidenHvxTruncate(Op, DAG);
|
||||
Results.push_back(T);
|
||||
break;
|
||||
}
|
||||
case ISD::BITCAST:
|
||||
if (isHvxBoolTy(ty(N->getOperand(0)))) {
|
||||
SDValue Op(N, 0);
|
||||
@ -2103,8 +2127,22 @@ HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
bool
|
||||
HexagonTargetLowering::shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const {
|
||||
assert(!Subtarget.isHVXVectorType(Ty, true));
|
||||
auto Action = getPreferredHvxVectorAction(Ty);
|
||||
if (Action == TargetLoweringBase::TypeWidenVector) {
|
||||
EVT WideTy = getTypeToTransformTo(*DAG.getContext(), Ty);
|
||||
assert(WideTy.isSimple());
|
||||
return Subtarget.isHVXVectorType(WideTy.getSimpleVT(), true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
HexagonTargetLowering::isHvxOperation(SDNode *N, SelectionDAG &DAG) const {
|
||||
if (!Subtarget.useHVXOps())
|
||||
return false;
|
||||
// If the type of any result, or any operand type are HVX vector types,
|
||||
// this is an HVX operation.
|
||||
auto IsHvxTy = [this](EVT Ty) {
|
||||
@ -2122,15 +2160,7 @@ HexagonTargetLowering::isHvxOperation(SDNode *N, SelectionDAG &DAG) const {
|
||||
if (!Op.getValueType().isSimple())
|
||||
return false;
|
||||
MVT ValTy = ty(Op);
|
||||
if (ValTy.isVector()) {
|
||||
auto Action = getPreferredVectorAction(ValTy);
|
||||
if (Action == TargetLoweringBase::TypeWidenVector) {
|
||||
EVT WideTy = getTypeToTransformTo(*DAG.getContext(), ValTy);
|
||||
assert(WideTy.isSimple());
|
||||
return Subtarget.isHVXVectorType(WideTy.getSimpleVT(), true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ValTy.isVector() && shouldWidenToHvx(ValTy, DAG);
|
||||
};
|
||||
|
||||
for (int i = 0, e = N->getNumValues(); i != e; ++i) {
|
||||
|
34
test/CodeGen/Hexagon/autohvx/isel-truncate-legal.ll
Normal file
34
test/CodeGen/Hexagon/autohvx/isel-truncate-legal.ll
Normal file
@ -0,0 +1,34 @@
|
||||
; RUN: llc -march=hexagon -hexagon-hvx-widen=32 < %s | FileCheck %s
|
||||
|
||||
; Truncating a type-to-be-widenened to a legal type (v8i8).
|
||||
; Check that this compiles successfully.
|
||||
; CHECK-LABEL: f0:
|
||||
; CHECK: dealloc_return
|
||||
|
||||
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
|
||||
target triple = "hexagon"
|
||||
|
||||
define dllexport void @f0(i8* %a0) local_unnamed_addr #0 {
|
||||
b0:
|
||||
%v0 = load i8, i8* undef, align 1
|
||||
%v1 = zext i8 %v0 to i16
|
||||
%v2 = add i16 0, %v1
|
||||
%v3 = icmp sgt i16 %v2, 1
|
||||
%v4 = select i1 %v3, i16 %v2, i16 1
|
||||
%v5 = udiv i16 -32768, %v4
|
||||
%v6 = zext i16 %v5 to i32
|
||||
%v7 = insertelement <8 x i32> undef, i32 %v6, i32 0
|
||||
%v8 = shufflevector <8 x i32> %v7, <8 x i32> undef, <8 x i32> zeroinitializer
|
||||
%v9 = load <8 x i16>, <8 x i16>* undef, align 2
|
||||
%v10 = sext <8 x i16> %v9 to <8 x i32>
|
||||
%v11 = mul nsw <8 x i32> %v8, %v10
|
||||
%v12 = add nsw <8 x i32> %v11, <i32 16384, i32 16384, i32 16384, i32 16384, i32 16384, i32 16384, i32 16384, i32 16384>
|
||||
%v13 = lshr <8 x i32> %v12, <i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>
|
||||
%v14 = trunc <8 x i32> %v13 to <8 x i8>
|
||||
%v15 = getelementptr inbounds i8, i8* %a0, i32 undef
|
||||
%v16 = bitcast i8* %v15 to <8 x i8>*
|
||||
store <8 x i8> %v14, <8 x i8>* %v16, align 1
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+hvx,+hvx-length128b" }
|
Loading…
Reference in New Issue
Block a user