mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[DAGCombine] Truncate BUILD_VECTOR operators if necessary when constant folding vectors
Summary: The BUILD_VECTOR node will truncate its operators to match the type. We need to take this into account when constant folding - we need to perform a truncation before constant folding the elements. This is because the upper bits can change the result, depending on the operation type (for example this is the case for min/max). This change also adds a regression test. Reviewers: jmolloy Subscribers: jmolloy, llvm-commits Differential Revision: http://reviews.llvm.org/D12697 llvm-svn: 247265
This commit is contained in:
parent
52c8c7c3ff
commit
82abdf7e36
@ -13325,20 +13325,34 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
|
||||
|
||||
EVT VT = LHSOp.getValueType();
|
||||
EVT RVT = RHSOp.getValueType();
|
||||
if (RVT != VT) {
|
||||
// Integer BUILD_VECTOR operands may have types larger than the element
|
||||
// size (e.g., when the element type is not legal). Prior to type
|
||||
// legalization, the types may not match between the two BUILD_VECTORS.
|
||||
// Truncate one of the operands to make them match.
|
||||
if (RVT.getSizeInBits() > VT.getSizeInBits()) {
|
||||
RHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, RHSOp);
|
||||
} else {
|
||||
LHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), RVT, LHSOp);
|
||||
VT = RVT;
|
||||
}
|
||||
EVT ST = VT;
|
||||
|
||||
if (RVT.getSizeInBits() < VT.getSizeInBits())
|
||||
ST = RVT;
|
||||
|
||||
// Integer BUILD_VECTOR operands may have types larger than the element
|
||||
// size (e.g., when the element type is not legal). Prior to type
|
||||
// legalization, the types may not match between the two BUILD_VECTORS.
|
||||
// Truncate the operands to make them match.
|
||||
if (VT.getSizeInBits() != LHS.getValueType().getScalarSizeInBits()) {
|
||||
EVT ScalarT = LHS.getValueType().getScalarType();
|
||||
LHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), ScalarT, LHSOp);
|
||||
VT = LHSOp.getValueType();
|
||||
}
|
||||
if (RVT.getSizeInBits() != RHS.getValueType().getScalarSizeInBits()) {
|
||||
EVT ScalarT = RHS.getValueType().getScalarType();
|
||||
RHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), ScalarT, RHSOp);
|
||||
RVT = RHSOp.getValueType();
|
||||
}
|
||||
|
||||
SDValue FoldOp = DAG.getNode(N->getOpcode(), SDLoc(LHS), VT,
|
||||
LHSOp, RHSOp);
|
||||
|
||||
// We need the resulting constant to be legal if we are in a phase after
|
||||
// legalization, so zero extend to the smallest operand type if required.
|
||||
if (ST != VT && Level != BeforeLegalizeTypes)
|
||||
FoldOp = DAG.getNode(ISD::ANY_EXTEND, SDLoc(LHS), ST, FoldOp);
|
||||
|
||||
if (FoldOp.getOpcode() != ISD::UNDEF &&
|
||||
FoldOp.getOpcode() != ISD::Constant &&
|
||||
FoldOp.getOpcode() != ISD::ConstantFP)
|
||||
|
12
test/CodeGen/AArch64/aarch64-smax-constantfold.ll
Normal file
12
test/CodeGen/AArch64/aarch64-smax-constantfold.ll
Normal file
@ -0,0 +1,12 @@
|
||||
; RUN: llc -mtriple=aarch64-none-linux-gnu < %s -o -| FileCheck %s
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare <4 x i16> @llvm.aarch64.neon.smax.v4i16(<4 x i16>, <4 x i16>)
|
||||
|
||||
; CHECK-LABEL: test
|
||||
define <4 x i16> @test() {
|
||||
entry:
|
||||
; CHECK: movi d{{[0-9]+}}, #0000000000000000
|
||||
%0 = tail call <4 x i16> @llvm.aarch64.neon.smax.v4i16(<4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>, <4 x i16> zeroinitializer)
|
||||
ret <4 x i16> %0
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user