[CodeGen] Fix incorrect uses of getVectorNumElements()

I have fixed up some places in SelectionDAG::getNode() where we
used to assert that the number of vector elements for two types
are the same. I have changed such cases to assert that the
element counts are the same instead. I've added new tests that
exercise the code paths for all the truncations. All the extend
operations are covered by this existing test:

  CodeGen/AArch64/sve-sext-zext.ll

For the ISD::SETCC case I fixed this code path is exercised by
these existing tests:

  CodeGen/AArch64/sve-fcmp.ll
  CodeGen/AArch64/sve-intrinsics-int-compares-with-imm.ll

Differential Revision: https://reviews.llvm.org/D79399
This commit is contained in:
David Sherwood 2020-05-05 09:58:24 +01:00
parent 054ed1fd0b
commit 42c7a6d52b
2 changed files with 68 additions and 11 deletions

View File

@ -4626,8 +4626,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
"type is vector!");
if (Operand.getValueType() == VT) return Operand; // noop extension
assert((!VT.isVector() ||
VT.getVectorNumElements() ==
Operand.getValueType().getVectorNumElements()) &&
VT.getVectorElementCount() ==
Operand.getValueType().getVectorElementCount()) &&
"Vector element count mismatch!");
assert(Operand.getValueType().bitsLT(VT) &&
"Invalid sext node, dst < src!");
@ -4645,8 +4645,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
"type is vector!");
if (Operand.getValueType() == VT) return Operand; // noop extension
assert((!VT.isVector() ||
VT.getVectorNumElements() ==
Operand.getValueType().getVectorNumElements()) &&
VT.getVectorElementCount() ==
Operand.getValueType().getVectorElementCount()) &&
"Vector element count mismatch!");
assert(Operand.getValueType().bitsLT(VT) &&
"Invalid zext node, dst < src!");
@ -4664,8 +4664,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
"type is vector!");
if (Operand.getValueType() == VT) return Operand; // noop extension
assert((!VT.isVector() ||
VT.getVectorNumElements() ==
Operand.getValueType().getVectorNumElements()) &&
VT.getVectorElementCount() ==
Operand.getValueType().getVectorElementCount()) &&
"Vector element count mismatch!");
assert(Operand.getValueType().bitsLT(VT) &&
"Invalid anyext node, dst < src!");
@ -4694,8 +4694,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
"type is vector!");
if (Operand.getValueType() == VT) return Operand; // noop truncate
assert((!VT.isVector() ||
VT.getVectorNumElements() ==
Operand.getValueType().getVectorNumElements()) &&
VT.getVectorElementCount() ==
Operand.getValueType().getVectorElementCount()) &&
"Vector element count mismatch!");
assert(Operand.getValueType().bitsGT(VT) &&
"Invalid truncate node, src < dst!");
@ -5337,7 +5337,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
"SIGN_EXTEND_INREG type should be vector iff the operand "
"type is vector!");
assert((!EVT.isVector() ||
EVT.getVectorNumElements() == VT.getVectorNumElements()) &&
EVT.getVectorElementCount() == VT.getVectorElementCount()) &&
"Vector element counts must match in SIGN_EXTEND_INREG");
assert(EVT.bitsLE(VT) && "Not extending!");
if (EVT == VT) return N1; // Not actually extending
@ -5625,8 +5625,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
"SETCC operands must have the same type!");
assert(VT.isVector() == N1.getValueType().isVector() &&
"SETCC type should be vector iff the operand type is vector!");
assert((!VT.isVector() ||
VT.getVectorNumElements() == N1.getValueType().getVectorNumElements()) &&
assert((!VT.isVector() || VT.getVectorElementCount() ==
N1.getValueType().getVectorElementCount()) &&
"SETCC vector element counts must match!");
// Use FoldSetCC to simplify SETCC's.
if (SDValue V = FoldSetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get(), DL))

View File

@ -0,0 +1,57 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
; For all the functions below should the operation is a nop
define <vscale x 8 x i8> @trunc_i16toi8(<vscale x 8 x i16> %in) {
; CHECK-LABEL: trunc_i16toi8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ret
entry:
%out = trunc <vscale x 8 x i16> %in to <vscale x 8 x i8>
ret <vscale x 8 x i8> %out
}
define <vscale x 4 x i8> @trunc_i32toi8(<vscale x 4 x i32> %in) {
; CHECK-LABEL: trunc_i32toi8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ret
entry:
%out = trunc <vscale x 4 x i32> %in to <vscale x 4 x i8>
ret <vscale x 4 x i8> %out
}
define <vscale x 2 x i8> @trunc_i64toi8(<vscale x 2 x i64> %in) {
; CHECK-LABEL: trunc_i64toi8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ret
entry:
%out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i8>
ret <vscale x 2 x i8> %out
}
define <vscale x 4 x i16> @trunc_i32toi16(<vscale x 4 x i32> %in) {
; CHECK-LABEL: trunc_i32toi16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ret
entry:
%out = trunc <vscale x 4 x i32> %in to <vscale x 4 x i16>
ret <vscale x 4 x i16> %out
}
define <vscale x 2 x i16> @trunc_i64toi16(<vscale x 2 x i64> %in) {
; CHECK-LABEL: trunc_i64toi16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ret
entry:
%out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i16>
ret <vscale x 2 x i16> %out
}
define <vscale x 2 x i32> @trunc_i64toi32(<vscale x 2 x i64> %in) {
; CHECK-LABEL: trunc_i64toi32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ret
entry:
%out = trunc <vscale x 2 x i64> %in to <vscale x 2 x i32>
ret <vscale x 2 x i32> %out
}