diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index b46a1bc2abc6..3678327627b9 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -39321,6 +39321,7 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op, } break; } + case X86ISD::FANDN: case X86ISD::ANDNP: { KnownBits Known2; Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1); diff --git a/llvm/unittests/Target/X86/CMakeLists.txt b/llvm/unittests/Target/X86/CMakeLists.txt index b011681aa3b9..d4304438cfc9 100644 --- a/llvm/unittests/Target/X86/CMakeLists.txt +++ b/llvm/unittests/Target/X86/CMakeLists.txt @@ -24,4 +24,5 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(X86Tests MachineSizeOptsTest.cpp TernlogTest.cpp + X86SelectionDAGTest.cpp ) diff --git a/llvm/unittests/Target/X86/X86SelectionDAGTest.cpp b/llvm/unittests/Target/X86/X86SelectionDAGTest.cpp new file mode 100644 index 000000000000..b546908a4893 --- /dev/null +++ b/llvm/unittests/Target/X86/X86SelectionDAGTest.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "X86ISelLowering.h" +#include "llvm/Analysis/MemoryLocation.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/KnownBits.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "gtest/gtest.h" + +namespace llvm { + +class X86SelectionDAGTest : public testing::Test { +protected: + const TargetSubtargetInfo *STI; + + static void SetUpTestCase() { + LLVMInitializeX86TargetInfo(); + LLVMInitializeX86Target(); + LLVMInitializeX86TargetMC(); + } + + void SetUp() override { + StringRef Assembly = "define void @f() { ret void }"; + + Triple TargetTriple("x86_64--"); + std::string Error; + const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); + + TargetOptions Options; + TM = std::unique_ptr(T->createTargetMachine( + TargetTriple, "x86-64-v4", "", Options, std::nullopt, std::nullopt, + CodeGenOptLevel::Aggressive)); + + SMDiagnostic SMError; + M = parseAssemblyString(Assembly, SMError, Context); + if (!M) + report_fatal_error(SMError.getMessage()); + M->setDataLayout(TM->createDataLayout()); + + F = M->getFunction("f"); + if (!F) + report_fatal_error("F?"); + + MachineModuleInfo MMI(TM.get()); + + STI = TM->getSubtargetImpl(*F); + MF = std::make_unique(*F, *TM, *STI, MMI.getContext(), 0); + + DAG = std::make_unique(*TM, CodeGenOptLevel::None); + if (!DAG) + report_fatal_error("DAG?"); + OptimizationRemarkEmitter ORE(F); + DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + MMI, nullptr); + } + + LLVMContext Context; + std::unique_ptr TM; + std::unique_ptr M; + Function *F; + std::unique_ptr MF; + std::unique_ptr DAG; +}; + +TEST_F(X86SelectionDAGTest, computeKnownBits_FANDN) { + SDLoc Loc; + + auto SrcF32 = DAG->getCopyFromReg(DAG->getEntryNode(), Loc, 1, MVT::f32); + auto SignBitF32 = DAG->getConstantFP(-0.0f, Loc, MVT::f32); + auto OpF32 = DAG->getNode(X86ISD::FANDN, Loc, MVT::f32, SignBitF32, SrcF32); + KnownBits KnownF32 = DAG->computeKnownBits(OpF32); + EXPECT_TRUE(KnownF32.isNonNegative()); + + auto Src2xF64 = DAG->getCopyFromReg(DAG->getEntryNode(), Loc, 1, MVT::v2f64); + auto ZeroF64 = DAG->getConstantFP(+0.0f, Loc, MVT::f64); + auto SignBitF64 = DAG->getConstantFP(-0.0f, Loc, MVT::f64); + auto HiSign2xF64 = + DAG->getBuildVector(MVT::v2f64, Loc, {ZeroF64, SignBitF64}); + auto Op2xF64 = + DAG->getNode(X86ISD::FANDN, Loc, MVT::v2f64, HiSign2xF64, Src2xF64); + KnownBits KnownAll2xF64 = DAG->computeKnownBits(Op2xF64); + KnownBits KnownLo2xF64 = DAG->computeKnownBits(Op2xF64, APInt(2, 1)); + KnownBits KnownHi2xF64 = DAG->computeKnownBits(Op2xF64, APInt(2, 2)); + EXPECT_FALSE(KnownAll2xF64.isNonNegative()); + EXPECT_FALSE(KnownLo2xF64.isNonNegative()); + EXPECT_TRUE(KnownHi2xF64.isNonNegative()); +} + +} // end namespace llvm diff --git a/llvm/utils/gn/secondary/llvm/unittests/Target/X86/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Target/X86/BUILD.gn index af2c6d38d951..e70ccd67b401 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Target/X86/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Target/X86/BUILD.gn @@ -21,5 +21,6 @@ unittest("X86Tests") { sources = [ "MachineSizeOptsTest.cpp", "TernlogTest.cpp", + "X86SelectionDAGTest.cpp", ] }