6 #include <gtest/gtest.h>
22 #include <llvm/IR/DerivedTypes.h>
23 #include <llvm/IR/Instructions.h>
24 #include <llvm/IR/LLVMContext.h>
56 int vectorization = GetParam();
60 auto & graph = rvsdgModule->Rvsdg();
67 std::shared_ptr<const jlm::rvsdg::Type> bits32V, bits64V, pointerTypeV;
68 if (vectorization == 0)
72 pointerTypeV = pointerType;
82 const size_t sizeofX = 8 * std::max(1, vectorization);
88 graph.GetRootRegion(),
94 auto x = lambda->GetFunctionArguments()[0];
102 if (vectorization == 0)
111 return *jlm::rvsdg::CreateOpNode<jlm::llvm::VectorUnaryOperation>(
114 std::static_pointer_cast<const jlm::llvm::VectorType>(operand.Type()),
115 std::static_pointer_cast<const jlm::llvm::VectorType>(resultType))
130 auto lambdaOutput = lambda->finalize({ &bitcast });
137 llvm::LLVMContext context;
142 llvm::Type * expectedBits32 = llvm::Type::getInt32Ty(context);
143 llvm::Type * expectedBits64 = llvm::Type::getInt64Ty(context);
144 llvm::Type * expectedPointer = llvm::PointerType::getUnqual(context);
146 if (vectorization != 0)
148 auto ec = llvm::ElementCount::getFixed(vectorization);
149 expectedBits32 = llvm::VectorType::get(expectedBits32, ec);
150 expectedBits64 = llvm::VectorType::get(expectedBits64, ec);
151 expectedPointer = llvm::VectorType::get(expectedPointer, ec);
154 auto byteEc = llvm::ElementCount::getFixed(sizeofX);
155 llvm::Type * expectedByteVector = llvm::VectorType::get(llvm::Type::getInt8Ty(context), byteEc);
157 auto llvmFunction = llvmModule->getFunction(
"f");
158 ASSERT_NE(llvmFunction,
nullptr);
159 EXPECT_EQ(llvmFunction->getReturnType(), expectedByteVector);
160 ASSERT_EQ(llvmFunction->arg_size(), 1u);
161 EXPECT_EQ(llvmFunction->arg_begin()->getType(), expectedBits32);
166 size_t numInttoptr = 0;
167 size_t numPtrtoint = 0;
168 size_t numBitcasts = 0;
170 for (
auto & basicBlock : *llvmFunction)
172 for (
auto & instruction : basicBlock)
174 if (
auto * zextInstruction = llvm::dyn_cast<llvm::ZExtInst>(&instruction))
177 EXPECT_EQ(zextInstruction->getSrcTy(), expectedBits32);
178 EXPECT_EQ(zextInstruction->getDestTy(), expectedBits64);
180 else if (
auto * truncInstruction = llvm::dyn_cast<llvm::TruncInst>(&instruction))
183 EXPECT_EQ(truncInstruction->getSrcTy(), expectedBits64);
184 EXPECT_EQ(truncInstruction->getDestTy(), expectedBits32);
186 else if (
auto * sextInstruction = llvm::dyn_cast<llvm::SExtInst>(&instruction))
189 EXPECT_EQ(sextInstruction->getSrcTy(), expectedBits32);
190 EXPECT_EQ(sextInstruction->getDestTy(), expectedBits64);
192 else if (
auto * intToPtrInstruction = llvm::dyn_cast<llvm::IntToPtrInst>(&instruction))
195 EXPECT_EQ(intToPtrInstruction->getSrcTy(), expectedBits64);
196 EXPECT_EQ(intToPtrInstruction->getDestTy(), expectedPointer);
198 else if (
auto * ptrToIntInstruction = llvm::dyn_cast<llvm::PtrToIntInst>(&instruction))
201 EXPECT_EQ(ptrToIntInstruction->getSrcTy(), expectedPointer);
202 EXPECT_EQ(ptrToIntInstruction->getDestTy(), expectedBits64);
204 else if (
auto * bitcastInstruction = llvm::dyn_cast<llvm::BitCastInst>(&instruction))
207 EXPECT_EQ(bitcastInstruction->getSrcTy(), expectedBits64);
208 EXPECT_EQ(bitcastInstruction->getDestTy(), expectedByteVector);
213 auto * returnInstruction =
214 llvm::dyn_cast<llvm::ReturnInst>(llvmFunction->back().getTerminator());
215 ASSERT_NE(returnInstruction,
nullptr);
216 auto * bitcastInstruction =
217 llvm::dyn_cast<llvm::BitCastInst>(returnInstruction->getReturnValue());
218 EXPECT_NE(bitcastInstruction,
nullptr);
220 EXPECT_EQ(numZext, 1u);
221 EXPECT_EQ(numTrunc, 1u);
222 EXPECT_EQ(numSext, 1u);
223 EXPECT_EQ(numInttoptr, 1u);
224 EXPECT_EQ(numPtrtoint, 1u);
225 EXPECT_EQ(numBitcasts, 1u);
230 LlvmBackendCastingTests,
232 testing::Values(0, 1, 2, 4, 8));
static jlm::util::StatisticsCollector statisticsCollector
TEST_P(LlvmBackendCastingFixture, AllIntegerCasts)
INSTANTIATE_TEST_SUITE_P(LlvmBackendCastingTests, LlvmBackendCastingFixture, testing::Values(0, 1, 2, 4, 8))
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *operand, std::shared_ptr< const jlm::rvsdg::Type > type)
static std::shared_ptr< const FixedVectorType > Create(std::shared_ptr< const rvsdg::Type > type, size_t size)
static std::unique_ptr<::llvm::Module > CreateAndConvertModule(InterProceduralGraphModule &ipGraphModule, ::llvm::LLVMContext &ctx)
static std::unique_ptr< LlvmLambdaOperation > Create(std::shared_ptr< const jlm::rvsdg::FunctionType > type, std::string name, const jlm::llvm::Linkage &linkage, jlm::llvm::CallingConvention callingConvention, jlm::llvm::AttributeSet attributes)
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
static std::shared_ptr< const PointerType > Create()
static std::unique_ptr< InterProceduralGraphModule > CreateAndConvertModule(LlvmRvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
static std::shared_ptr< const FunctionType > Create(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> argumentTypes, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> resultTypes)
static GraphExport & Create(Output &origin, std::string name)
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
SimpleNode & CreateOpNode(const std::vector< Output * > &operands, OperatorArguments... operatorArguments)
Creates a simple node characterized by its operator.