[llvm] r247265 - [DAGCombine] Truncate BUILD_VECTOR operators if necessary when constant folding vectors
Silviu Baranga via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 03:34:34 PDT 2015
Author: sbaranga
Date: Thu Sep 10 05:34:34 2015
New Revision: 247265
URL: http://llvm.org/viewvc/llvm-project?rev=247265&view=rev
Log:
[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
Added:
llvm/trunk/test/CodeGen/AArch64/aarch64-smax-constantfold.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=247265&r1=247264&r2=247265&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Sep 10 05:34:34 2015
@@ -13325,20 +13325,34 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNo
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)
Added: llvm/trunk/test/CodeGen/AArch64/aarch64-smax-constantfold.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/aarch64-smax-constantfold.ll?rev=247265&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/aarch64-smax-constantfold.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/aarch64-smax-constantfold.ll Thu Sep 10 05:34:34 2015
@@ -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
+}
More information about the llvm-commits
mailing list