forked from OSchip/llvm-project
[WebAssembly] Fix ISel crash in SIGN_EXTEND_INREG lowering
Summary: The code previously assumed that the index of a vector extract was constant, but this was not always true. This patch fixes the problem by bailing out of the lowering if the index is nonconstant and also replaces `static_cast`s in the lowering function with `cast`s because the latter contain type-checking asserts that would make similar issues easier to find and debug. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D81025
This commit is contained in:
parent
969d2d1ea9
commit
25af2126f9
|
|
@ -1388,23 +1388,23 @@ WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
|
||||||
MVT VecT = Extract.getOperand(0).getSimpleValueType();
|
MVT VecT = Extract.getOperand(0).getSimpleValueType();
|
||||||
if (VecT.getVectorElementType().getSizeInBits() > 32)
|
if (VecT.getVectorElementType().getSizeInBits() > 32)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
MVT ExtractedLaneT = static_cast<VTSDNode *>(Op.getOperand(1).getNode())
|
MVT ExtractedLaneT =
|
||||||
->getVT()
|
cast<VTSDNode>(Op.getOperand(1).getNode())->getVT().getSimpleVT();
|
||||||
.getSimpleVT();
|
|
||||||
MVT ExtractedVecT =
|
MVT ExtractedVecT =
|
||||||
MVT::getVectorVT(ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits());
|
MVT::getVectorVT(ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits());
|
||||||
if (ExtractedVecT == VecT)
|
if (ExtractedVecT == VecT)
|
||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
// Bitcast vector to appropriate type to ensure ISel pattern coverage
|
// Bitcast vector to appropriate type to ensure ISel pattern coverage
|
||||||
const SDValue &Index = Extract.getOperand(1);
|
const SDNode *Index = Extract.getOperand(1).getNode();
|
||||||
unsigned IndexVal =
|
if (!isa<ConstantSDNode>(Index))
|
||||||
static_cast<ConstantSDNode *>(Index.getNode())->getZExtValue();
|
return SDValue();
|
||||||
|
unsigned IndexVal = cast<ConstantSDNode>(Index)->getZExtValue();
|
||||||
unsigned Scale =
|
unsigned Scale =
|
||||||
ExtractedVecT.getVectorNumElements() / VecT.getVectorNumElements();
|
ExtractedVecT.getVectorNumElements() / VecT.getVectorNumElements();
|
||||||
assert(Scale > 1);
|
assert(Scale > 1);
|
||||||
SDValue NewIndex =
|
SDValue NewIndex =
|
||||||
DAG.getConstant(IndexVal * Scale, DL, Index.getValueType());
|
DAG.getConstant(IndexVal * Scale, DL, Index->getValueType(0));
|
||||||
SDValue NewExtract = DAG.getNode(
|
SDValue NewExtract = DAG.getNode(
|
||||||
ISD::EXTRACT_VECTOR_ELT, DL, Extract.getValueType(),
|
ISD::EXTRACT_VECTOR_ELT, DL, Extract.getValueType(),
|
||||||
DAG.getBitcast(ExtractedVecT, Extract.getOperand(0)), NewIndex);
|
DAG.getBitcast(ExtractedVecT, Extract.getOperand(0)), NewIndex);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -mattr=+simd128 | FileCheck %s
|
||||||
|
|
||||||
|
; A regression test for a bug in the lowering of SIGN_EXTEND_INREG
|
||||||
|
; with SIMD and without sign-ext where ISel would crash if the index
|
||||||
|
; of the vector extract was not a constant.
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
|
target triple = "wasm32"
|
||||||
|
|
||||||
|
; CHECK-LABEL: foo:
|
||||||
|
; CHECK-NEXT: .functype foo () -> (f32)
|
||||||
|
; CHECK: i32x4.load16x4_u
|
||||||
|
; CHECK: f32.convert_i32_s
|
||||||
|
define float @foo() {
|
||||||
|
%1 = load <4 x i16>, <4 x i16>* undef, align 8
|
||||||
|
%2 = load i32, i32* undef, align 4
|
||||||
|
%vecext = extractelement <4 x i16> %1, i32 %2
|
||||||
|
%conv = sitofp i16 %vecext to float
|
||||||
|
ret float %conv
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue