diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -322,16 +322,26 @@ } bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits) { - EVT VT = Op.getValueType(); - unsigned NumElts = VT.isVector() ? VT.getVectorNumElements() : 1; - APInt DemandedElts = APInt::getAllOnesValue(NumElts); - return SimplifyDemandedBits(Op, DemandedBits, DemandedElts); + TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations); + KnownBits Known; + if (!TLI.SimplifyDemandedBits(Op, DemandedBits, Known, TLO, 0, false)) + 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 /// if things it uses can be simplified as it only uses some of the /// elements. If so, return true. bool SimplifyDemandedVectorElts(SDValue Op) { + // TODO: For now just pretend it cannot be simplified. + if (Op.getValueType().isScalableVector()) + return false; + unsigned NumElts = Op.getValueType().getVectorNumElements(); APInt DemandedElts = APInt::getAllOnesValue(NumElts); return SimplifyDemandedVectorElts(Op, DemandedElts); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -590,6 +590,16 @@ unsigned Depth, bool AssumeSingleUse) const { 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::getAllOnesValue(VT.getVectorNumElements()) : APInt(1, 1); @@ -842,6 +852,15 @@ assert(Op.getScalarValueSizeInBits() == BitWidth && "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(); assert((!Op.getValueType().isVector() || NumElts == Op.getValueType().getVectorNumElements()) && @@ -852,9 +871,6 @@ SDLoc dl(Op); auto &DL = TLO.DAG.getDataLayout(); - // Don't know anything. - Known = KnownBits(BitWidth); - // Undef operand. if (Op.isUndef()) return false; @@ -2256,11 +2272,16 @@ APInt DemandedElts = OriginalDemandedElts; unsigned NumElts = DemandedElts.getBitWidth(); assert(VT.isVector() && "Expected vector op"); - assert(VT.getVectorNumElements() == NumElts && - "Mask size mismatches value type element count!"); 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. if (Op.isUndef()) { KnownUndef.setAllBits(); diff --git a/llvm/test/CodeGen/AArch64/sve-int-arith.ll b/llvm/test/CodeGen/AArch64/sve-int-arith.ll --- a/llvm/test/CodeGen/AArch64/sve-int-arith.ll +++ b/llvm/test/CodeGen/AArch64/sve-int-arith.ll @@ -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 @add_i64( %a, %b) { ; CHECK-LABEL: add_i64 diff --git a/llvm/test/CodeGen/AArch64/sve-int-imm.ll b/llvm/test/CodeGen/AArch64/sve-int-imm.ll --- a/llvm/test/CodeGen/AArch64/sve-int-imm.ll +++ b/llvm/test/CodeGen/AArch64/sve-int-imm.ll @@ -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 diff --git a/llvm/test/CodeGen/AArch64/sve-int-log-imm.ll b/llvm/test/CodeGen/AArch64/sve-int-log-imm.ll --- a/llvm/test/CodeGen/AArch64/sve-int-log-imm.ll +++ b/llvm/test/CodeGen/AArch64/sve-int-log-imm.ll @@ -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 diff --git a/llvm/test/CodeGen/AArch64/sve-int-log.ll b/llvm/test/CodeGen/AArch64/sve-int-log.ll --- a/llvm/test/CodeGen/AArch64/sve-int-log.ll +++ b/llvm/test/CodeGen/AArch64/sve-int-log.ll @@ -1,5 +1,8 @@ ; 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 @and_d( %a, %b) { ; CHECK-LABEL: and_d: diff --git a/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll b/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll --- a/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll +++ b/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll @@ -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) diff --git a/llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll b/llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll --- a/llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll +++ b/llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll @@ -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 () diff --git a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp b/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp --- a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp +++ b/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp @@ -196,6 +196,61 @@ 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. TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) { if (!TM)