mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[CodeGen] Fix SimplifyDemandedBits for scalable vectors
For now I have changed SimplifyDemandedBits and it's various callers to assume we know nothing for scalable vectors and to ignore the demanded bits completely. I have also done something similar for SimplifyDemandedVectorElts. These changes fix up lots of warnings due to calls to EVT::getVectorNumElements() for types with scalable vectors. These functions are all used for optimisations, rather than functional requirements. In future we can revisit this code if there is a need to improve code quality for SVE. Differential Revision: https://reviews.llvm.org/D80537
This commit is contained in:
parent
f5847de3ec
commit
08a3df5192
@ -322,16 +322,26 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits) {
|
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits) {
|
||||||
EVT VT = Op.getValueType();
|
TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
|
||||||
unsigned NumElts = VT.isVector() ? VT.getVectorNumElements() : 1;
|
KnownBits Known;
|
||||||
APInt DemandedElts = APInt::getAllOnesValue(NumElts);
|
if (!TLI.SimplifyDemandedBits(Op, DemandedBits, Known, TLO, 0, false))
|
||||||
return SimplifyDemandedBits(Op, DemandedBits, DemandedElts);
|
return false;
|
||||||
|
|
||||||
|
// Revisit the node.
|
||||||
|
AddToWorklist(Op.getNode());
|
||||||
|
|
||||||
|
CommitTargetLoweringOpt(TLO);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check the specified vector node value to see if it can be simplified or
|
/// Check the specified vector node value to see if it can be simplified or
|
||||||
/// if things it uses can be simplified as it only uses some of the
|
/// if things it uses can be simplified as it only uses some of the
|
||||||
/// elements. If so, return true.
|
/// elements. If so, return true.
|
||||||
bool SimplifyDemandedVectorElts(SDValue Op) {
|
bool SimplifyDemandedVectorElts(SDValue Op) {
|
||||||
|
// TODO: For now just pretend it cannot be simplified.
|
||||||
|
if (Op.getValueType().isScalableVector())
|
||||||
|
return false;
|
||||||
|
|
||||||
unsigned NumElts = Op.getValueType().getVectorNumElements();
|
unsigned NumElts = Op.getValueType().getVectorNumElements();
|
||||||
APInt DemandedElts = APInt::getAllOnesValue(NumElts);
|
APInt DemandedElts = APInt::getAllOnesValue(NumElts);
|
||||||
return SimplifyDemandedVectorElts(Op, DemandedElts);
|
return SimplifyDemandedVectorElts(Op, DemandedElts);
|
||||||
|
@ -590,6 +590,16 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits,
|
|||||||
unsigned Depth,
|
unsigned Depth,
|
||||||
bool AssumeSingleUse) const {
|
bool AssumeSingleUse) const {
|
||||||
EVT VT = Op.getValueType();
|
EVT VT = Op.getValueType();
|
||||||
|
|
||||||
|
// TODO: We can probably do more work on calculating the known bits and
|
||||||
|
// simplifying the operations for scalable vectors, but for now we just
|
||||||
|
// bail out.
|
||||||
|
if (VT.isScalableVector()) {
|
||||||
|
// Pretend we don't know anything for now.
|
||||||
|
Known = KnownBits(DemandedBits.getBitWidth());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
APInt DemandedElts = VT.isVector()
|
APInt DemandedElts = VT.isVector()
|
||||||
? APInt::getAllOnesValue(VT.getVectorNumElements())
|
? APInt::getAllOnesValue(VT.getVectorNumElements())
|
||||||
: APInt(1, 1);
|
: APInt(1, 1);
|
||||||
@ -842,6 +852,15 @@ bool TargetLowering::SimplifyDemandedBits(
|
|||||||
assert(Op.getScalarValueSizeInBits() == BitWidth &&
|
assert(Op.getScalarValueSizeInBits() == BitWidth &&
|
||||||
"Mask size mismatches value type size!");
|
"Mask size mismatches value type size!");
|
||||||
|
|
||||||
|
// Don't know anything.
|
||||||
|
Known = KnownBits(BitWidth);
|
||||||
|
|
||||||
|
// TODO: We can probably do more work on calculating the known bits and
|
||||||
|
// simplifying the operations for scalable vectors, but for now we just
|
||||||
|
// bail out.
|
||||||
|
if (Op.getValueType().isScalableVector())
|
||||||
|
return false;
|
||||||
|
|
||||||
unsigned NumElts = OriginalDemandedElts.getBitWidth();
|
unsigned NumElts = OriginalDemandedElts.getBitWidth();
|
||||||
assert((!Op.getValueType().isVector() ||
|
assert((!Op.getValueType().isVector() ||
|
||||||
NumElts == Op.getValueType().getVectorNumElements()) &&
|
NumElts == Op.getValueType().getVectorNumElements()) &&
|
||||||
@ -852,9 +871,6 @@ bool TargetLowering::SimplifyDemandedBits(
|
|||||||
SDLoc dl(Op);
|
SDLoc dl(Op);
|
||||||
auto &DL = TLO.DAG.getDataLayout();
|
auto &DL = TLO.DAG.getDataLayout();
|
||||||
|
|
||||||
// Don't know anything.
|
|
||||||
Known = KnownBits(BitWidth);
|
|
||||||
|
|
||||||
// Undef operand.
|
// Undef operand.
|
||||||
if (Op.isUndef())
|
if (Op.isUndef())
|
||||||
return false;
|
return false;
|
||||||
@ -2256,11 +2272,16 @@ bool TargetLowering::SimplifyDemandedVectorElts(
|
|||||||
APInt DemandedElts = OriginalDemandedElts;
|
APInt DemandedElts = OriginalDemandedElts;
|
||||||
unsigned NumElts = DemandedElts.getBitWidth();
|
unsigned NumElts = DemandedElts.getBitWidth();
|
||||||
assert(VT.isVector() && "Expected vector op");
|
assert(VT.isVector() && "Expected vector op");
|
||||||
assert(VT.getVectorNumElements() == NumElts &&
|
|
||||||
"Mask size mismatches value type element count!");
|
|
||||||
|
|
||||||
KnownUndef = KnownZero = APInt::getNullValue(NumElts);
|
KnownUndef = KnownZero = APInt::getNullValue(NumElts);
|
||||||
|
|
||||||
|
// TODO: For now we assume we know nothing about scalable vectors.
|
||||||
|
if (VT.isScalableVector())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
assert(VT.getVectorNumElements() == NumElts &&
|
||||||
|
"Mask size mismatches value type element count!");
|
||||||
|
|
||||||
// Undef operand.
|
// Undef operand.
|
||||||
if (Op.isUndef()) {
|
if (Op.isUndef()) {
|
||||||
KnownUndef.setAllBits();
|
KnownUndef.setAllBits();
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
|
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
|
||||||
|
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
|
||||||
|
|
||||||
|
; WARN-NOT: warning
|
||||||
|
|
||||||
define <vscale x 2 x i64> @add_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {
|
define <vscale x 2 x i64> @add_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {
|
||||||
; CHECK-LABEL: add_i64
|
; CHECK-LABEL: add_i64
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
|
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
|
||||||
|
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
|
||||||
|
|
||||||
|
; WARN-NOT: warning
|
||||||
|
|
||||||
;
|
;
|
||||||
; SVE Arith Vector Immediate Unpredicated CodeGen
|
; SVE Arith Vector Immediate Unpredicated CodeGen
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
|
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
|
||||||
|
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
|
||||||
|
|
||||||
|
; WARN-NOT: warning
|
||||||
|
|
||||||
;
|
;
|
||||||
; SVE Logical Vector Immediate Unpredicated CodeGen
|
; SVE Logical Vector Immediate Unpredicated CodeGen
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
|
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
|
||||||
|
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
|
||||||
|
|
||||||
|
; WARN-NOT: warning
|
||||||
|
|
||||||
define <vscale x 2 x i64> @and_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {
|
define <vscale x 2 x i64> @and_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {
|
||||||
; CHECK-LABEL: and_d:
|
; CHECK-LABEL: and_d:
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
|
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
|
||||||
|
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
|
||||||
|
|
||||||
|
; WARN-NOT: warning
|
||||||
|
|
||||||
;
|
;
|
||||||
; CLASTA (Vectors)
|
; CLASTA (Vectors)
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
|
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
|
||||||
|
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
|
||||||
|
|
||||||
|
; WARN-NOT: warning
|
||||||
|
|
||||||
;
|
;
|
||||||
; Converting to svbool_t (<vscale x 16 x i1>)
|
; Converting to svbool_t (<vscale x 16 x i1>)
|
||||||
|
@ -196,6 +196,61 @@ TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {
|
||||||
|
if (!TM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TargetLowering TL(*TM);
|
||||||
|
|
||||||
|
SDLoc Loc;
|
||||||
|
auto Int8VT = EVT::getIntegerVT(Context, 8);
|
||||||
|
auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16);
|
||||||
|
SDValue UnknownOp = DAG->getRegister(0, InVecVT);
|
||||||
|
SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
|
||||||
|
SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S);
|
||||||
|
SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
|
||||||
|
|
||||||
|
SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
|
||||||
|
SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S);
|
||||||
|
|
||||||
|
SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
|
||||||
|
// N0 = ?000?0?0
|
||||||
|
// Mask2V = 01010101
|
||||||
|
// =>
|
||||||
|
// Known.Zero = 00100000 (0xAA)
|
||||||
|
KnownBits Known;
|
||||||
|
APInt DemandedBits = APInt(8, 0xFF);
|
||||||
|
TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
|
||||||
|
EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
|
||||||
|
EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {
|
||||||
|
if (!TM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TargetLowering TL(*TM);
|
||||||
|
|
||||||
|
SDLoc Loc;
|
||||||
|
auto Int8VT = EVT::getIntegerVT(Context, 8);
|
||||||
|
auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true);
|
||||||
|
SDValue UnknownOp = DAG->getRegister(0, InVecVT);
|
||||||
|
SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);
|
||||||
|
SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S);
|
||||||
|
SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);
|
||||||
|
|
||||||
|
SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);
|
||||||
|
SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S);
|
||||||
|
|
||||||
|
SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);
|
||||||
|
|
||||||
|
KnownBits Known;
|
||||||
|
APInt DemandedBits = APInt(8, 0xFF);
|
||||||
|
TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
|
||||||
|
EXPECT_FALSE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
|
||||||
|
EXPECT_EQ(Known.Zero, APInt(8, 0));
|
||||||
|
}
|
||||||
|
|
||||||
// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
|
// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
|
||||||
TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
|
TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
|
||||||
if (!TM)
|
if (!TM)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user