From 94687c0f43a409fb8113f8320b4858fb2939ef96 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 27 Mar 2014 17:23:24 +0000 Subject: [PATCH] R600/SI: Fix unreachable with a sext_in_reg to an illegal type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204945 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDGPUISelLowering.cpp | 18 ++++++++++++++++++ lib/Target/R600/AMDGPUISelLowering.h | 4 ++++ lib/Target/R600/R600ISelLowering.cpp | 4 +++- lib/Target/R600/R600ISelLowering.h | 6 +++--- test/CodeGen/R600/sext-in-reg.ll | 21 +++++++++++++++++++++ 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/Target/R600/AMDGPUISelLowering.cpp b/lib/Target/R600/AMDGPUISelLowering.cpp index 8c6d7c89188..ba7ce13491d 100644 --- a/lib/Target/R600/AMDGPUISelLowering.cpp +++ b/lib/Target/R600/AMDGPUISelLowering.cpp @@ -333,6 +333,24 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) return Op; } +void AMDGPUTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl &Results, + SelectionDAG &DAG) const { + switch (N->getOpcode()) { + case ISD::SIGN_EXTEND_INREG: + // Different parts of legalization seem to interpret which type of + // sign_extend_inreg is the one to check for custom lowering. The extended + // from type is what really matters, but some places check for custom + // lowering of the result type. This results in trying to use + // ReplaceNodeResults to sext_in_reg to an illegal type, so we'll just do + // nothing here and let the illegal result integer be handled normally. + return; + + default: + return; + } +} + SDValue AMDGPUTargetLowering::LowerConstantInitializer(const Constant* Init, const GlobalValue *GV, const SDValue &InitPtr, diff --git a/lib/Target/R600/AMDGPUISelLowering.h b/lib/Target/R600/AMDGPUISelLowering.h index a2bd91100d5..2d40e264264 100644 --- a/lib/Target/R600/AMDGPUISelLowering.h +++ b/lib/Target/R600/AMDGPUISelLowering.h @@ -103,6 +103,10 @@ public: } virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; + virtual void ReplaceNodeResults(SDNode * N, + SmallVectorImpl &Results, + SelectionDAG &DAG) const override; + SDValue LowerIntrinsicIABS(SDValue Op, SelectionDAG &DAG) const; SDValue LowerIntrinsicLRP(SDValue Op, SelectionDAG &DAG) const; SDValue LowerMinMax(SDValue Op, SelectionDAG &DAG) const; diff --git a/lib/Target/R600/R600ISelLowering.cpp b/lib/Target/R600/R600ISelLowering.cpp index 4d15321fd02..6405a82b3a8 100644 --- a/lib/Target/R600/R600ISelLowering.cpp +++ b/lib/Target/R600/R600ISelLowering.cpp @@ -762,7 +762,9 @@ void R600TargetLowering::ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { switch (N->getOpcode()) { - default: return; + default: + AMDGPUTargetLowering::ReplaceNodeResults(N, Results, DAG); + return; case ISD::FP_TO_UINT: Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG)); return; case ISD::LOAD: { diff --git a/lib/Target/R600/R600ISelLowering.h b/lib/Target/R600/R600ISelLowering.h index 3cca93306b5..22ef72873ef 100644 --- a/lib/Target/R600/R600ISelLowering.h +++ b/lib/Target/R600/R600ISelLowering.h @@ -28,9 +28,9 @@ public: MachineBasicBlock * BB) const; virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; - void ReplaceNodeResults(SDNode * N, - SmallVectorImpl &Results, - SelectionDAG &DAG) const; + virtual void ReplaceNodeResults(SDNode * N, + SmallVectorImpl &Results, + SelectionDAG &DAG) const override; virtual SDValue LowerFormalArguments( SDValue Chain, CallingConv::ID CallConv, diff --git a/test/CodeGen/R600/sext-in-reg.ll b/test/CodeGen/R600/sext-in-reg.ll index cb8b5d7bb2e..ee9f499662c 100644 --- a/test/CodeGen/R600/sext-in-reg.ll +++ b/test/CodeGen/R600/sext-in-reg.ll @@ -1,6 +1,9 @@ ; RUN: llc < %s -march=r600 -mcpu=SI | FileCheck -check-prefix=SI -check-prefix=FUNC %s ; RUN: llc < %s -march=r600 -mcpu=cypress | FileCheck -check-prefix=EG -check-prefix=FUNC %s +declare i32 @llvm.AMDGPU.imax(i32, i32) nounwind readnone + + ; FUNC-LABEL: @sext_in_reg_i1_i32 ; SI: S_LOAD_DWORD [[ARG:s[0-9]+]], ; SI: V_BFE_I32 [[EXTRACT:v[0-9]+]], [[ARG]], 0, 1 @@ -248,3 +251,21 @@ define void @testcase_3(i8 addrspace(1)* %out, i8 %a) nounwind { store i8 %xor, i8 addrspace(1)* %out ret void } + +; FIXME: The BFE should really be eliminated. I think it should happen +; when computeMaskedBitsForTargetNode is implemented for imax. + +; FUNC-LABEL: @sext_in_reg_to_illegal_type +; SI: BUFFER_LOAD_SBYTE +; SI: V_MAX_I32 +; SI: V_BFE_I32 +; SI: BUFFER_STORE_SHORT +define void @sext_in_reg_to_illegal_type(i16 addrspace(1)* nocapture %out, i8 addrspace(1)* nocapture %src) nounwind { + %tmp5 = load i8 addrspace(1)* %src, align 1 + %tmp2 = sext i8 %tmp5 to i32 + %tmp3 = tail call i32 @llvm.AMDGPU.imax(i32 %tmp2, i32 0) nounwind readnone + %tmp4 = trunc i32 %tmp3 to i8 + %tmp6 = sext i8 %tmp4 to i16 + store i16 %tmp6, i16 addrspace(1)* %out, align 2 + ret void +} -- 2.34.1