1976 lines · cpp
1//===- llvm/unittest/IR/InstructionsTest.cpp - Instructions unit tests ----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/IR/Instructions.h"10#include "llvm-c/Core.h"11#include "llvm/ADT/CombinationGenerator.h"12#include "llvm/ADT/STLExtras.h"13#include "llvm/Analysis/ValueTracking.h"14#include "llvm/Analysis/VectorUtils.h"15#include "llvm/AsmParser/Parser.h"16#include "llvm/IR/BasicBlock.h"17#include "llvm/IR/Constants.h"18#include "llvm/IR/DataLayout.h"19#include "llvm/IR/DebugInfoMetadata.h"20#include "llvm/IR/DerivedTypes.h"21#include "llvm/IR/FPEnv.h"22#include "llvm/IR/Function.h"23#include "llvm/IR/IRBuilder.h"24#include "llvm/IR/LLVMContext.h"25#include "llvm/IR/MDBuilder.h"26#include "llvm/IR/Module.h"27#include "llvm/IR/NoFolder.h"28#include "llvm/IR/Operator.h"29#include "llvm/Support/CommandLine.h"30#include "llvm/Support/Compiler.h"31#include "llvm/Support/SourceMgr.h"32#include "gmock/gmock-matchers.h"33#include "gtest/gtest.h"34#include <memory>35 36namespace llvm {37namespace {38 39static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {40 SMDiagnostic Err;41 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);42 if (!Mod)43 Err.print("InstructionsTests", errs());44 return Mod;45}46 47TEST(InstructionsTest, ReturnInst) {48 LLVMContext C;49 50 // test for PR658951 const ReturnInst* r0 = ReturnInst::Create(C);52 EXPECT_EQ(r0->getNumOperands(), 0U);53 EXPECT_EQ(r0->op_begin(), r0->op_end());54 55 IntegerType* Int1 = IntegerType::get(C, 1);56 Constant* One = ConstantInt::get(Int1, 1, true);57 const ReturnInst* r1 = ReturnInst::Create(C, One);58 EXPECT_EQ(1U, r1->getNumOperands());59 User::const_op_iterator b(r1->op_begin());60 EXPECT_NE(r1->op_end(), b);61 EXPECT_EQ(One, *b);62 EXPECT_EQ(One, r1->getOperand(0));63 ++b;64 EXPECT_EQ(r1->op_end(), b);65 66 // clean up67 delete r0;68 delete r1;69}70 71// Test fixture that provides a module and a single function within it. Useful72// for tests that need to refer to the function in some way.73class ModuleWithFunctionTest : public testing::Test {74protected:75 ModuleWithFunctionTest() : M(new Module("MyModule", Ctx)) {76 FArgTypes.push_back(Type::getInt8Ty(Ctx));77 FArgTypes.push_back(Type::getInt32Ty(Ctx));78 FArgTypes.push_back(Type::getInt64Ty(Ctx));79 FunctionType *FTy =80 FunctionType::get(Type::getVoidTy(Ctx), FArgTypes, false);81 F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());82 }83 84 LLVMContext Ctx;85 std::unique_ptr<Module> M;86 SmallVector<Type *, 3> FArgTypes;87 Function *F;88};89 90TEST_F(ModuleWithFunctionTest, CallInst) {91 Value *Args[] = {ConstantInt::get(Type::getInt8Ty(Ctx), 20),92 ConstantInt::get(Type::getInt32Ty(Ctx), 9999),93 ConstantInt::get(Type::getInt64Ty(Ctx), 42)};94 std::unique_ptr<CallInst> Call(CallInst::Create(F, Args));95 96 // Make sure iteration over a call's arguments works as expected.97 unsigned Idx = 0;98 for (Value *Arg : Call->args()) {99 EXPECT_EQ(FArgTypes[Idx], Arg->getType());100 EXPECT_EQ(Call->getArgOperand(Idx)->getType(), Arg->getType());101 Idx++;102 }103 104 Call->addRetAttr(Attribute::get(Call->getContext(), "test-str-attr"));105 EXPECT_TRUE(Call->hasRetAttr("test-str-attr"));106 EXPECT_FALSE(Call->hasRetAttr("not-on-call"));107 108 Call->addFnAttr(Attribute::get(Call->getContext(), "test-str-fn-attr"));109 ASSERT_TRUE(Call->hasFnAttr("test-str-fn-attr"));110 Call->removeFnAttr("test-str-fn-attr");111 EXPECT_FALSE(Call->hasFnAttr("test-str-fn-attr"));112}113 114TEST_F(ModuleWithFunctionTest, InvokeInst) {115 BasicBlock *BB1 = BasicBlock::Create(Ctx, "", F);116 BasicBlock *BB2 = BasicBlock::Create(Ctx, "", F);117 118 Value *Args[] = {ConstantInt::get(Type::getInt8Ty(Ctx), 20),119 ConstantInt::get(Type::getInt32Ty(Ctx), 9999),120 ConstantInt::get(Type::getInt64Ty(Ctx), 42)};121 std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create(F, BB1, BB2, Args));122 123 // Make sure iteration over invoke's arguments works as expected.124 unsigned Idx = 0;125 for (Value *Arg : Invoke->args()) {126 EXPECT_EQ(FArgTypes[Idx], Arg->getType());127 EXPECT_EQ(Invoke->getArgOperand(Idx)->getType(), Arg->getType());128 Idx++;129 }130}131 132TEST(InstructionsTest, BranchInst) {133 LLVMContext C;134 135 // Make a BasicBlocks136 BasicBlock* bb0 = BasicBlock::Create(C);137 BasicBlock* bb1 = BasicBlock::Create(C);138 139 // Mandatory BranchInst140 const BranchInst* b0 = BranchInst::Create(bb0);141 142 EXPECT_TRUE(b0->isUnconditional());143 EXPECT_FALSE(b0->isConditional());144 EXPECT_EQ(1U, b0->getNumSuccessors());145 146 // check num operands147 EXPECT_EQ(1U, b0->getNumOperands());148 149 EXPECT_NE(b0->op_begin(), b0->op_end());150 EXPECT_EQ(b0->op_end(), std::next(b0->op_begin()));151 152 EXPECT_EQ(b0->op_end(), std::next(b0->op_begin()));153 154 IntegerType* Int1 = IntegerType::get(C, 1);155 Constant* One = ConstantInt::get(Int1, 1, true);156 157 // Conditional BranchInst158 BranchInst* b1 = BranchInst::Create(bb0, bb1, One);159 160 EXPECT_FALSE(b1->isUnconditional());161 EXPECT_TRUE(b1->isConditional());162 EXPECT_EQ(2U, b1->getNumSuccessors());163 164 // check num operands165 EXPECT_EQ(3U, b1->getNumOperands());166 167 User::const_op_iterator b(b1->op_begin());168 169 // check COND170 EXPECT_NE(b, b1->op_end());171 EXPECT_EQ(One, *b);172 EXPECT_EQ(One, b1->getOperand(0));173 EXPECT_EQ(One, b1->getCondition());174 ++b;175 176 // check ELSE177 EXPECT_EQ(bb1, *b);178 EXPECT_EQ(bb1, b1->getOperand(1));179 EXPECT_EQ(bb1, b1->getSuccessor(1));180 ++b;181 182 // check THEN183 EXPECT_EQ(bb0, *b);184 EXPECT_EQ(bb0, b1->getOperand(2));185 EXPECT_EQ(bb0, b1->getSuccessor(0));186 ++b;187 188 EXPECT_EQ(b1->op_end(), b);189 190 // clean up191 delete b0;192 delete b1;193 194 delete bb0;195 delete bb1;196}197 198TEST(InstructionsTest, CastInst) {199 LLVMContext C;200 201 Type *Int8Ty = Type::getInt8Ty(C);202 Type *Int16Ty = Type::getInt16Ty(C);203 Type *Int32Ty = Type::getInt32Ty(C);204 Type *Int64Ty = Type::getInt64Ty(C);205 Type *V8x8Ty = FixedVectorType::get(Int8Ty, 8);206 Type *V8x64Ty = FixedVectorType::get(Int64Ty, 8);207 208 Type *HalfTy = Type::getHalfTy(C);209 Type *FloatTy = Type::getFloatTy(C);210 Type *DoubleTy = Type::getDoubleTy(C);211 212 Type *V2Int32Ty = FixedVectorType::get(Int32Ty, 2);213 Type *V2Int64Ty = FixedVectorType::get(Int64Ty, 2);214 Type *V4Int16Ty = FixedVectorType::get(Int16Ty, 4);215 Type *V1Int16Ty = FixedVectorType::get(Int16Ty, 1);216 217 Type *VScaleV2Int32Ty = ScalableVectorType::get(Int32Ty, 2);218 Type *VScaleV2Int64Ty = ScalableVectorType::get(Int64Ty, 2);219 Type *VScaleV4Int16Ty = ScalableVectorType::get(Int16Ty, 4);220 Type *VScaleV1Int16Ty = ScalableVectorType::get(Int16Ty, 1);221 222 Type *PtrTy = PointerType::get(C, 0);223 Type *PtrAS1Ty = PointerType::get(C, 1);224 225 Type *V2PtrAS1Ty = FixedVectorType::get(PtrAS1Ty, 2);226 Type *V4PtrAS1Ty = FixedVectorType::get(PtrAS1Ty, 4);227 Type *VScaleV4PtrAS1Ty = ScalableVectorType::get(PtrAS1Ty, 4);228 229 Type *V2PtrTy = FixedVectorType::get(PtrTy, 2);230 Type *V4PtrTy = FixedVectorType::get(PtrTy, 4);231 Type *VScaleV2PtrTy = ScalableVectorType::get(PtrTy, 2);232 Type *VScaleV4PtrTy = ScalableVectorType::get(PtrTy, 4);233 234 const Constant* c8 = Constant::getNullValue(V8x8Ty);235 const Constant* c64 = Constant::getNullValue(V8x64Ty);236 237 const Constant *v2ptr32 = Constant::getNullValue(V2PtrTy);238 239 EXPECT_EQ(CastInst::Trunc, CastInst::getCastOpcode(c64, true, V8x8Ty, true));240 EXPECT_EQ(CastInst::SExt, CastInst::getCastOpcode(c8, true, V8x64Ty, true));241 242 EXPECT_FALSE(CastInst::isBitCastable(V8x64Ty, V8x8Ty));243 EXPECT_FALSE(CastInst::isBitCastable(V8x8Ty, V8x64Ty));244 245 // Check address space casts are rejected since we don't know the sizes here246 EXPECT_FALSE(CastInst::isBitCastable(PtrTy, PtrAS1Ty));247 EXPECT_FALSE(CastInst::isBitCastable(PtrAS1Ty, PtrTy));248 EXPECT_FALSE(CastInst::isBitCastable(V2PtrTy, V2PtrAS1Ty));249 EXPECT_FALSE(CastInst::isBitCastable(V2PtrAS1Ty, V2PtrTy));250 EXPECT_TRUE(CastInst::isBitCastable(V2PtrAS1Ty, V2PtrAS1Ty));251 EXPECT_EQ(CastInst::AddrSpaceCast,252 CastInst::getCastOpcode(v2ptr32, true, V2PtrAS1Ty, true));253 254 // Test mismatched number of elements for pointers255 EXPECT_FALSE(CastInst::isBitCastable(V2PtrAS1Ty, V4PtrAS1Ty));256 EXPECT_FALSE(CastInst::isBitCastable(V4PtrAS1Ty, V2PtrAS1Ty));257 EXPECT_FALSE(CastInst::isBitCastable(PtrTy, V2PtrTy));258 EXPECT_FALSE(CastInst::isBitCastable(V2PtrTy, PtrTy));259 260 EXPECT_TRUE(CastInst::isBitCastable(PtrTy, PtrTy));261 EXPECT_FALSE(CastInst::isBitCastable(DoubleTy, FloatTy));262 EXPECT_FALSE(CastInst::isBitCastable(FloatTy, DoubleTy));263 EXPECT_TRUE(CastInst::isBitCastable(FloatTy, FloatTy));264 EXPECT_TRUE(CastInst::isBitCastable(FloatTy, FloatTy));265 EXPECT_TRUE(CastInst::isBitCastable(FloatTy, Int32Ty));266 EXPECT_TRUE(CastInst::isBitCastable(Int16Ty, HalfTy));267 EXPECT_TRUE(CastInst::isBitCastable(Int32Ty, FloatTy));268 EXPECT_TRUE(CastInst::isBitCastable(V2Int32Ty, Int64Ty));269 270 EXPECT_TRUE(CastInst::isBitCastable(V2Int32Ty, V4Int16Ty));271 EXPECT_FALSE(CastInst::isBitCastable(Int32Ty, Int64Ty));272 EXPECT_FALSE(CastInst::isBitCastable(Int64Ty, Int32Ty));273 274 EXPECT_FALSE(CastInst::isBitCastable(V2PtrTy, Int64Ty));275 EXPECT_FALSE(CastInst::isBitCastable(Int64Ty, V2PtrTy));276 EXPECT_FALSE(CastInst::isBitCastable(V2Int32Ty, V2Int64Ty));277 EXPECT_FALSE(CastInst::isBitCastable(V2Int64Ty, V2Int32Ty));278 279 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,280 Constant::getNullValue(V4PtrTy), V2PtrTy));281 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,282 Constant::getNullValue(V2PtrTy), V4PtrTy));283 284 EXPECT_FALSE(CastInst::castIsValid(285 Instruction::AddrSpaceCast, Constant::getNullValue(V4PtrAS1Ty), V2PtrTy));286 EXPECT_FALSE(CastInst::castIsValid(287 Instruction::AddrSpaceCast, Constant::getNullValue(V2PtrTy), V4PtrAS1Ty));288 289 // Address space cast of fixed/scalable vectors of pointers to scalable/fixed290 // vector of pointers.291 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,292 Constant::getNullValue(VScaleV4PtrAS1Ty),293 V4PtrTy));294 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,295 Constant::getNullValue(V4PtrTy),296 VScaleV4PtrAS1Ty));297 // Address space cast of scalable vectors of pointers to scalable vector of298 // pointers.299 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,300 Constant::getNullValue(VScaleV4PtrAS1Ty),301 VScaleV2PtrTy));302 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,303 Constant::getNullValue(VScaleV2PtrTy),304 VScaleV4PtrAS1Ty));305 EXPECT_TRUE(CastInst::castIsValid(Instruction::AddrSpaceCast,306 Constant::getNullValue(VScaleV4PtrTy),307 VScaleV4PtrAS1Ty));308 // Same number of lanes, different address space.309 EXPECT_TRUE(CastInst::castIsValid(Instruction::AddrSpaceCast,310 Constant::getNullValue(VScaleV4PtrAS1Ty),311 VScaleV4PtrTy));312 // Same number of lanes, same address space.313 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,314 Constant::getNullValue(VScaleV4PtrTy),315 VScaleV4PtrTy));316 317 // Bit casting fixed/scalable vector to scalable/fixed vectors.318 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,319 Constant::getNullValue(V2Int32Ty),320 VScaleV2Int32Ty));321 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,322 Constant::getNullValue(V2Int64Ty),323 VScaleV2Int64Ty));324 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,325 Constant::getNullValue(V4Int16Ty),326 VScaleV4Int16Ty));327 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,328 Constant::getNullValue(VScaleV2Int32Ty),329 V2Int32Ty));330 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,331 Constant::getNullValue(VScaleV2Int64Ty),332 V2Int64Ty));333 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,334 Constant::getNullValue(VScaleV4Int16Ty),335 V4Int16Ty));336 337 // Bit casting scalable vectors to scalable vectors.338 EXPECT_TRUE(CastInst::castIsValid(Instruction::BitCast,339 Constant::getNullValue(VScaleV4Int16Ty),340 VScaleV2Int32Ty));341 EXPECT_TRUE(CastInst::castIsValid(Instruction::BitCast,342 Constant::getNullValue(VScaleV2Int32Ty),343 VScaleV4Int16Ty));344 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,345 Constant::getNullValue(VScaleV2Int64Ty),346 VScaleV2Int32Ty));347 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,348 Constant::getNullValue(VScaleV2Int32Ty),349 VScaleV2Int64Ty));350 351 // Bitcasting to/from <vscale x 1 x Ty>352 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,353 Constant::getNullValue(VScaleV1Int16Ty),354 V1Int16Ty));355 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,356 Constant::getNullValue(V1Int16Ty),357 VScaleV1Int16Ty));358 359 // Check that assertion is not hit when creating a cast with a vector of360 // pointers361 // First form362 BasicBlock *BB = BasicBlock::Create(C);363 Constant *NullV2I32Ptr = Constant::getNullValue(V2PtrTy);364 auto Inst1 = CastInst::CreatePointerCast(NullV2I32Ptr, V2Int32Ty, "foo", BB);365 366 Constant *NullVScaleV2I32Ptr = Constant::getNullValue(VScaleV2PtrTy);367 auto Inst1VScale = CastInst::CreatePointerCast(368 NullVScaleV2I32Ptr, VScaleV2Int32Ty, "foo.vscale", BB);369 370 // Second form371 auto Inst2 = CastInst::CreatePointerCast(NullV2I32Ptr, V2Int32Ty);372 auto Inst2VScale =373 CastInst::CreatePointerCast(NullVScaleV2I32Ptr, VScaleV2Int32Ty);374 375 delete Inst2;376 delete Inst2VScale;377 Inst1->eraseFromParent();378 Inst1VScale->eraseFromParent();379 delete BB;380}381 382TEST(InstructionsTest, CastCAPI) {383 LLVMContext C;384 385 Type *Int8Ty = Type::getInt8Ty(C);386 Type *Int64Ty = Type::getInt64Ty(C);387 388 Type *FloatTy = Type::getFloatTy(C);389 Type *DoubleTy = Type::getDoubleTy(C);390 391 Type *PtrTy = PointerType::get(C, 0);392 393 const Constant *C8 = Constant::getNullValue(Int8Ty);394 const Constant *C64 = Constant::getNullValue(Int64Ty);395 396 EXPECT_EQ(LLVMBitCast,397 LLVMGetCastOpcode(wrap(C64), true, wrap(Int64Ty), true));398 EXPECT_EQ(LLVMTrunc, LLVMGetCastOpcode(wrap(C64), true, wrap(Int8Ty), true));399 EXPECT_EQ(LLVMSExt, LLVMGetCastOpcode(wrap(C8), true, wrap(Int64Ty), true));400 EXPECT_EQ(LLVMZExt, LLVMGetCastOpcode(wrap(C8), false, wrap(Int64Ty), true));401 402 const Constant *CF32 = Constant::getNullValue(FloatTy);403 const Constant *CF64 = Constant::getNullValue(DoubleTy);404 405 EXPECT_EQ(LLVMFPToUI,406 LLVMGetCastOpcode(wrap(CF32), true, wrap(Int8Ty), false));407 EXPECT_EQ(LLVMFPToSI,408 LLVMGetCastOpcode(wrap(CF32), true, wrap(Int8Ty), true));409 EXPECT_EQ(LLVMUIToFP,410 LLVMGetCastOpcode(wrap(C8), false, wrap(FloatTy), true));411 EXPECT_EQ(LLVMSIToFP, LLVMGetCastOpcode(wrap(C8), true, wrap(FloatTy), true));412 EXPECT_EQ(LLVMFPTrunc,413 LLVMGetCastOpcode(wrap(CF64), true, wrap(FloatTy), true));414 EXPECT_EQ(LLVMFPExt,415 LLVMGetCastOpcode(wrap(CF32), true, wrap(DoubleTy), true));416 417 const Constant *CPtr8 = Constant::getNullValue(PtrTy);418 419 EXPECT_EQ(LLVMPtrToInt,420 LLVMGetCastOpcode(wrap(CPtr8), true, wrap(Int8Ty), true));421 EXPECT_EQ(LLVMIntToPtr, LLVMGetCastOpcode(wrap(C8), true, wrap(PtrTy), true));422 423 Type *V8x8Ty = FixedVectorType::get(Int8Ty, 8);424 Type *V8x64Ty = FixedVectorType::get(Int64Ty, 8);425 const Constant *CV8 = Constant::getNullValue(V8x8Ty);426 const Constant *CV64 = Constant::getNullValue(V8x64Ty);427 428 EXPECT_EQ(LLVMTrunc, LLVMGetCastOpcode(wrap(CV64), true, wrap(V8x8Ty), true));429 EXPECT_EQ(LLVMSExt, LLVMGetCastOpcode(wrap(CV8), true, wrap(V8x64Ty), true));430 431 Type *PtrAS1Ty = PointerType::get(C, 1);432 Type *V2PtrAS1Ty = FixedVectorType::get(PtrAS1Ty, 2);433 Type *V2PtrTy = FixedVectorType::get(PtrTy, 2);434 const Constant *CV2Ptr = Constant::getNullValue(V2PtrTy);435 436 EXPECT_EQ(LLVMAddrSpaceCast,437 LLVMGetCastOpcode(wrap(CV2Ptr), true, wrap(V2PtrAS1Ty), true));438}439 440TEST(InstructionsTest, VectorGep) {441 LLVMContext C;442 443 // Type Definitions444 Type *I32Ty = IntegerType::get(C, 32);445 PointerType *PtrTy = PointerType::get(C, 0);446 VectorType *V2xPTy = FixedVectorType::get(PtrTy, 2);447 448 // Test different aspects of the vector-of-pointers type449 // and GEPs which use this type.450 ConstantInt *Ci32a = ConstantInt::get(C, APInt(32, 1492));451 ConstantInt *Ci32b = ConstantInt::get(C, APInt(32, 1948));452 std::vector<Constant*> ConstVa(2, Ci32a);453 std::vector<Constant*> ConstVb(2, Ci32b);454 Constant *C2xi32a = ConstantVector::get(ConstVa);455 Constant *C2xi32b = ConstantVector::get(ConstVb);456 457 CastInst *PtrVecA = new IntToPtrInst(C2xi32a, V2xPTy);458 CastInst *PtrVecB = new IntToPtrInst(C2xi32b, V2xPTy);459 460 ICmpInst *ICmp0 = new ICmpInst(ICmpInst::ICMP_SGT, PtrVecA, PtrVecB);461 ICmpInst *ICmp1 = new ICmpInst(ICmpInst::ICMP_ULT, PtrVecA, PtrVecB);462 EXPECT_NE(ICmp0, ICmp1); // suppress warning.463 464 BasicBlock* BB0 = BasicBlock::Create(C);465 // Test InsertAtEnd ICmpInst constructor.466 ICmpInst *ICmp2 = new ICmpInst(BB0, ICmpInst::ICMP_SGE, PtrVecA, PtrVecB);467 EXPECT_NE(ICmp0, ICmp2); // suppress warning.468 469 GetElementPtrInst *Gep0 = GetElementPtrInst::Create(I32Ty, PtrVecA, C2xi32a);470 GetElementPtrInst *Gep1 = GetElementPtrInst::Create(I32Ty, PtrVecA, C2xi32b);471 GetElementPtrInst *Gep2 = GetElementPtrInst::Create(I32Ty, PtrVecB, C2xi32a);472 GetElementPtrInst *Gep3 = GetElementPtrInst::Create(I32Ty, PtrVecB, C2xi32b);473 474 CastInst *BTC0 = new BitCastInst(Gep0, V2xPTy);475 CastInst *BTC1 = new BitCastInst(Gep1, V2xPTy);476 CastInst *BTC2 = new BitCastInst(Gep2, V2xPTy);477 CastInst *BTC3 = new BitCastInst(Gep3, V2xPTy);478 479 Value *S0 = BTC0->stripPointerCasts();480 Value *S1 = BTC1->stripPointerCasts();481 Value *S2 = BTC2->stripPointerCasts();482 Value *S3 = BTC3->stripPointerCasts();483 484 EXPECT_NE(S0, Gep0);485 EXPECT_NE(S1, Gep1);486 EXPECT_NE(S2, Gep2);487 EXPECT_NE(S3, Gep3);488 489 int64_t Offset;490 DataLayout TD("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3"491 "2:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-s:64:64-f80"492 ":128:128-n8:16:32:64-S128");493 // Make sure we don't crash494 GetPointerBaseWithConstantOffset(Gep0, Offset, TD);495 GetPointerBaseWithConstantOffset(Gep1, Offset, TD);496 GetPointerBaseWithConstantOffset(Gep2, Offset, TD);497 GetPointerBaseWithConstantOffset(Gep3, Offset, TD);498 499 // Gep of Geps500 GetElementPtrInst *GepII0 = GetElementPtrInst::Create(I32Ty, Gep0, C2xi32b);501 GetElementPtrInst *GepII1 = GetElementPtrInst::Create(I32Ty, Gep1, C2xi32a);502 GetElementPtrInst *GepII2 = GetElementPtrInst::Create(I32Ty, Gep2, C2xi32b);503 GetElementPtrInst *GepII3 = GetElementPtrInst::Create(I32Ty, Gep3, C2xi32a);504 505 EXPECT_EQ(GepII0->getNumIndices(), 1u);506 EXPECT_EQ(GepII1->getNumIndices(), 1u);507 EXPECT_EQ(GepII2->getNumIndices(), 1u);508 EXPECT_EQ(GepII3->getNumIndices(), 1u);509 510 EXPECT_FALSE(GepII0->hasAllZeroIndices());511 EXPECT_FALSE(GepII1->hasAllZeroIndices());512 EXPECT_FALSE(GepII2->hasAllZeroIndices());513 EXPECT_FALSE(GepII3->hasAllZeroIndices());514 515 delete GepII0;516 delete GepII1;517 delete GepII2;518 delete GepII3;519 520 delete BTC0;521 delete BTC1;522 delete BTC2;523 delete BTC3;524 525 delete Gep0;526 delete Gep1;527 delete Gep2;528 delete Gep3;529 530 ICmp2->eraseFromParent();531 delete BB0;532 533 delete ICmp0;534 delete ICmp1;535 delete PtrVecA;536 delete PtrVecB;537}538 539TEST(InstructionsTest, FPMathOperator) {540 LLVMContext Context;541 IRBuilder<> Builder(Context);542 MDBuilder MDHelper(Context);543 Instruction *I = Builder.CreatePHI(Builder.getDoubleTy(), 0);544 MDNode *MD1 = MDHelper.createFPMath(1.0);545 Value *V1 = Builder.CreateFAdd(I, I, "", MD1);546 EXPECT_TRUE(isa<FPMathOperator>(V1));547 FPMathOperator *O1 = cast<FPMathOperator>(V1);548 EXPECT_EQ(O1->getFPAccuracy(), 1.0);549 V1->deleteValue();550 I->deleteValue();551}552 553TEST(InstructionTest, ConstrainedTrans) {554 LLVMContext Context;555 std::unique_ptr<Module> M(new Module("MyModule", Context));556 FunctionType *FTy =557 FunctionType::get(Type::getVoidTy(Context),558 {Type::getFloatTy(Context), Type::getFloatTy(Context),559 Type::getInt32Ty(Context)},560 false);561 auto *F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());562 auto *BB = BasicBlock::Create(Context, "bb", F);563 IRBuilder<> Builder(Context);564 Builder.SetInsertPoint(BB);565 auto *Arg0 = F->arg_begin();566 auto *Arg1 = F->arg_begin() + 1;567 568 {569 auto *I = cast<Instruction>(Builder.CreateFAdd(Arg0, Arg1));570 EXPECT_EQ(Intrinsic::experimental_constrained_fadd,571 getConstrainedIntrinsicID(*I));572 }573 574 {575 auto *I = cast<Instruction>(576 Builder.CreateFPToSI(Arg0, Type::getInt32Ty(Context)));577 EXPECT_EQ(Intrinsic::experimental_constrained_fptosi,578 getConstrainedIntrinsicID(*I));579 }580 581 {582 auto *I = cast<Instruction>(Builder.CreateIntrinsic(583 Intrinsic::ceil, {Type::getFloatTy(Context)}, {Arg0}));584 EXPECT_EQ(Intrinsic::experimental_constrained_ceil,585 getConstrainedIntrinsicID(*I));586 }587 588 {589 auto *I = cast<Instruction>(Builder.CreateFCmpOEQ(Arg0, Arg1));590 EXPECT_EQ(Intrinsic::experimental_constrained_fcmp,591 getConstrainedIntrinsicID(*I));592 }593 594 {595 auto *Arg2 = F->arg_begin() + 2;596 auto *I = cast<Instruction>(Builder.CreateAdd(Arg2, Arg2));597 EXPECT_EQ(Intrinsic::not_intrinsic, getConstrainedIntrinsicID(*I));598 }599 600 {601 auto *I = cast<Instruction>(Builder.CreateConstrainedFPBinOp(602 Intrinsic::experimental_constrained_fadd, Arg0, Arg0));603 EXPECT_EQ(Intrinsic::not_intrinsic, getConstrainedIntrinsicID(*I));604 }605}606 607TEST(InstructionsTest, isEliminableCastPair) {608 LLVMContext C;609 DataLayout DL1("p1:32:32-p2:64:64:64:32");610 611 Type *Int16Ty = Type::getInt16Ty(C);612 Type *Int32Ty = Type::getInt32Ty(C);613 Type *Int64Ty = Type::getInt64Ty(C);614 Type *PtrTy64 = PointerType::get(C, 0);615 Type *PtrTy32 = PointerType::get(C, 1);616 Type *PtrTy64_32 = PointerType::get(C, 2);617 618 // Source and destination pointers have same size -> bitcast.619 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,620 CastInst::IntToPtr, PtrTy32, Int64Ty,621 PtrTy32, &DL1),622 CastInst::BitCast);623 624 // Source and destination have unknown sizes.625 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,626 CastInst::IntToPtr, PtrTy32, Int64Ty,627 PtrTy32, nullptr),628 0U);629 630 // Middle pointer big enough -> bitcast.631 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,632 CastInst::PtrToInt, Int64Ty, PtrTy64,633 Int64Ty, &DL1),634 CastInst::BitCast);635 636 // Middle pointer too small -> fail.637 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,638 CastInst::PtrToInt, Int64Ty, PtrTy32,639 Int64Ty, &DL1),640 0U);641 642 // Destination larger than source. Pointer type same as destination.643 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,644 CastInst::PtrToInt, Int16Ty, PtrTy64,645 Int64Ty, &DL1),646 CastInst::ZExt);647 648 // Destination larger than source. Pointer type different from destination.649 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,650 CastInst::PtrToInt, Int16Ty, PtrTy32,651 Int64Ty, &DL1),652 CastInst::ZExt);653 654 // Destination smaller than source. Pointer type same as source.655 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,656 CastInst::PtrToInt, Int64Ty, PtrTy64,657 Int16Ty, &DL1),658 CastInst::Trunc);659 660 // Destination smaller than source. Pointer type different from source.661 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,662 CastInst::PtrToInt, Int64Ty, PtrTy32,663 Int16Ty, &DL1),664 CastInst::Trunc);665 666 // ptrtoaddr with address size != pointer size. Truncating case.667 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,668 CastInst::PtrToAddr, Int64Ty,669 PtrTy64_32, Int32Ty, &DL1),670 CastInst::Trunc);671 672 // ptrtoaddr with address size != pointer size. Non-truncating case.673 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,674 CastInst::PtrToAddr, Int32Ty,675 PtrTy64_32, Int32Ty, &DL1),676 CastInst::BitCast);677 678 // Test that we don't eliminate bitcasts between different address spaces,679 // or if we don't have available pointer size information.680 DataLayout DL2("e-p:32:32:32-p1:16:16:16-p2:64:64:64-i1:8:8-i8:8:8-i16:16:16"681 "-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64"682 "-v128:128:128-a:0:64-s:64:64-f80:128:128-n8:16:32:64-S128");683 684 Type *Int64PtrTyAS1 = PointerType::get(C, 1);685 Type *Int64PtrTyAS2 = PointerType::get(C, 2);686 687 // Cannot simplify inttoptr, addrspacecast688 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,689 CastInst::AddrSpaceCast, Int16Ty,690 Int64PtrTyAS1, Int64PtrTyAS2, &DL2),691 0U);692 693 // Cannot simplify addrspacecast, ptrtoint694 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::AddrSpaceCast,695 CastInst::PtrToInt, Int64PtrTyAS1,696 Int64PtrTyAS2, Int16Ty, &DL2),697 0U);698 699 // Pass since the bitcast address spaces are the same700 EXPECT_EQ(CastInst::isEliminableCastPair(701 CastInst::IntToPtr, CastInst::BitCast, Int16Ty, Int64PtrTyAS1,702 Int64PtrTyAS1, nullptr),703 CastInst::IntToPtr);704}705 706TEST(InstructionsTest, CloneCall) {707 LLVMContext C;708 Type *Int32Ty = Type::getInt32Ty(C);709 Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty};710 FunctionType *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false);711 Value *Callee = Constant::getNullValue(PointerType::getUnqual(C));712 Value *Args[] = {713 ConstantInt::get(Int32Ty, 1),714 ConstantInt::get(Int32Ty, 2),715 ConstantInt::get(Int32Ty, 3)716 };717 std::unique_ptr<CallInst> Call(718 CallInst::Create(FnTy, Callee, Args, "result"));719 720 // Test cloning the tail call kind.721 CallInst::TailCallKind Kinds[] = {CallInst::TCK_None, CallInst::TCK_Tail,722 CallInst::TCK_MustTail};723 for (CallInst::TailCallKind TCK : Kinds) {724 Call->setTailCallKind(TCK);725 std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone()));726 EXPECT_EQ(Call->getTailCallKind(), Clone->getTailCallKind());727 }728 Call->setTailCallKind(CallInst::TCK_None);729 730 // Test cloning an attribute.731 {732 AttrBuilder AB(C);733 AB.addAttribute(Attribute::NoUnwind);734 Call->setAttributes(735 AttributeList::get(C, AttributeList::FunctionIndex, AB));736 std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone()));737 EXPECT_TRUE(Clone->doesNotThrow());738 }739}740 741TEST(InstructionsTest, AlterCallBundles) {742 LLVMContext C;743 Type *Int32Ty = Type::getInt32Ty(C);744 FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);745 Value *Callee = Constant::getNullValue(PointerType::getUnqual(C));746 Value *Args[] = {ConstantInt::get(Int32Ty, 42)};747 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty));748 std::unique_ptr<CallInst> Call(749 CallInst::Create(FnTy, Callee, Args, OldBundle, "result"));750 Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail);751 AttrBuilder AB(C);752 AB.addAttribute(Attribute::Cold);753 Call->setAttributes(AttributeList::get(C, AttributeList::FunctionIndex, AB));754 Call->setDebugLoc(DebugLoc(MDNode::get(C, {})));755 756 OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7));757 std::unique_ptr<CallInst> Clone(CallInst::Create(Call.get(), NewBundle));758 EXPECT_EQ(Call->arg_size(), Clone->arg_size());759 EXPECT_EQ(Call->getArgOperand(0), Clone->getArgOperand(0));760 EXPECT_EQ(Call->getCallingConv(), Clone->getCallingConv());761 EXPECT_EQ(Call->getTailCallKind(), Clone->getTailCallKind());762 EXPECT_TRUE(Clone->hasFnAttr(Attribute::AttrKind::Cold));763 EXPECT_EQ(Call->getDebugLoc(), Clone->getDebugLoc());764 EXPECT_EQ(Clone->getNumOperandBundles(), 1U);765 EXPECT_TRUE(Clone->getOperandBundle("after"));766}767 768TEST(InstructionsTest, AlterInvokeBundles) {769 LLVMContext C;770 Type *Int32Ty = Type::getInt32Ty(C);771 FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);772 Value *Callee = Constant::getNullValue(PointerType::getUnqual(C));773 Value *Args[] = {ConstantInt::get(Int32Ty, 42)};774 std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C));775 std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C));776 OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty));777 std::unique_ptr<InvokeInst> Invoke(778 InvokeInst::Create(FnTy, Callee, NormalDest.get(), UnwindDest.get(), Args,779 OldBundle, "result"));780 AttrBuilder AB(C);781 AB.addAttribute(Attribute::Cold);782 Invoke->setAttributes(783 AttributeList::get(C, AttributeList::FunctionIndex, AB));784 Invoke->setDebugLoc(DebugLoc(MDNode::get(C, {})));785 786 OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7));787 std::unique_ptr<InvokeInst> Clone(788 InvokeInst::Create(Invoke.get(), NewBundle));789 EXPECT_EQ(Invoke->getNormalDest(), Clone->getNormalDest());790 EXPECT_EQ(Invoke->getUnwindDest(), Clone->getUnwindDest());791 EXPECT_EQ(Invoke->arg_size(), Clone->arg_size());792 EXPECT_EQ(Invoke->getArgOperand(0), Clone->getArgOperand(0));793 EXPECT_EQ(Invoke->getCallingConv(), Clone->getCallingConv());794 EXPECT_TRUE(Clone->hasFnAttr(Attribute::AttrKind::Cold));795 EXPECT_EQ(Invoke->getDebugLoc(), Clone->getDebugLoc());796 EXPECT_EQ(Clone->getNumOperandBundles(), 1U);797 EXPECT_TRUE(Clone->getOperandBundle("after"));798}799 800TEST_F(ModuleWithFunctionTest, DropPoisonGeneratingFlags) {801 auto *OnlyBB = BasicBlock::Create(Ctx, "bb", F);802 auto *Arg0 = &*F->arg_begin();803 804 IRBuilder<NoFolder> B(Ctx);805 B.SetInsertPoint(OnlyBB);806 807 {808 auto *UI =809 cast<Instruction>(B.CreateUDiv(Arg0, Arg0, "", /*isExact*/ true));810 ASSERT_TRUE(UI->isExact());811 UI->dropPoisonGeneratingFlags();812 ASSERT_FALSE(UI->isExact());813 }814 815 {816 auto *ShrI =817 cast<Instruction>(B.CreateLShr(Arg0, Arg0, "", /*isExact*/ true));818 ASSERT_TRUE(ShrI->isExact());819 ShrI->dropPoisonGeneratingFlags();820 ASSERT_FALSE(ShrI->isExact());821 }822 823 {824 auto *AI = cast<Instruction>(825 B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ false));826 ASSERT_TRUE(AI->hasNoUnsignedWrap());827 AI->dropPoisonGeneratingFlags();828 ASSERT_FALSE(AI->hasNoUnsignedWrap());829 ASSERT_FALSE(AI->hasNoSignedWrap());830 }831 832 {833 auto *SI = cast<Instruction>(834 B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ false, /*HasNSW*/ true));835 ASSERT_TRUE(SI->hasNoSignedWrap());836 SI->dropPoisonGeneratingFlags();837 ASSERT_FALSE(SI->hasNoUnsignedWrap());838 ASSERT_FALSE(SI->hasNoSignedWrap());839 }840 841 {842 auto *ShlI = cast<Instruction>(843 B.CreateShl(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ true));844 ASSERT_TRUE(ShlI->hasNoSignedWrap());845 ASSERT_TRUE(ShlI->hasNoUnsignedWrap());846 ShlI->dropPoisonGeneratingFlags();847 ASSERT_FALSE(ShlI->hasNoUnsignedWrap());848 ASSERT_FALSE(ShlI->hasNoSignedWrap());849 }850 851 {852 Value *GEPBase = Constant::getNullValue(B.getPtrTy());853 auto *GI = cast<GetElementPtrInst>(854 B.CreateInBoundsGEP(B.getInt8Ty(), GEPBase, Arg0));855 ASSERT_TRUE(GI->isInBounds());856 GI->dropPoisonGeneratingFlags();857 ASSERT_FALSE(GI->isInBounds());858 }859}860 861TEST(InstructionsTest, GEPIndices) {862 LLVMContext Context;863 IRBuilder<NoFolder> Builder(Context);864 Type *ElementTy = Builder.getInt8Ty();865 Type *ArrTy = ArrayType::get(ArrayType::get(ElementTy, 64), 64);866 Value *Indices[] = {867 Builder.getInt32(0),868 Builder.getInt32(13),869 Builder.getInt32(42) };870 871 Value *V = Builder.CreateGEP(872 ArrTy, UndefValue::get(PointerType::getUnqual(Context)), Indices);873 ASSERT_TRUE(isa<GetElementPtrInst>(V));874 875 auto *GEPI = cast<GetElementPtrInst>(V);876 ASSERT_NE(GEPI->idx_begin(), GEPI->idx_end());877 ASSERT_EQ(GEPI->idx_end(), std::next(GEPI->idx_begin(), 3));878 EXPECT_EQ(Indices[0], GEPI->idx_begin()[0]);879 EXPECT_EQ(Indices[1], GEPI->idx_begin()[1]);880 EXPECT_EQ(Indices[2], GEPI->idx_begin()[2]);881 EXPECT_EQ(GEPI->idx_begin(), GEPI->indices().begin());882 EXPECT_EQ(GEPI->idx_end(), GEPI->indices().end());883 884 const auto *CGEPI = GEPI;885 ASSERT_NE(CGEPI->idx_begin(), CGEPI->idx_end());886 ASSERT_EQ(CGEPI->idx_end(), std::next(CGEPI->idx_begin(), 3));887 EXPECT_EQ(Indices[0], CGEPI->idx_begin()[0]);888 EXPECT_EQ(Indices[1], CGEPI->idx_begin()[1]);889 EXPECT_EQ(Indices[2], CGEPI->idx_begin()[2]);890 EXPECT_EQ(CGEPI->idx_begin(), CGEPI->indices().begin());891 EXPECT_EQ(CGEPI->idx_end(), CGEPI->indices().end());892 893 delete GEPI;894}895 896TEST(InstructionsTest, ZeroIndexGEP) {897 LLVMContext Context;898 DataLayout DL;899 Type *PtrTy = PointerType::getUnqual(Context);900 auto *GEP = GetElementPtrInst::Create(Type::getInt8Ty(Context),901 PoisonValue::get(PtrTy), {});902 903 APInt Offset(DL.getIndexTypeSizeInBits(PtrTy), 0);904 EXPECT_TRUE(GEP->accumulateConstantOffset(DL, Offset));905 EXPECT_TRUE(Offset.isZero());906 907 delete GEP;908}909 910TEST(InstructionsTest, SwitchInst) {911 LLVMContext C;912 913 std::unique_ptr<BasicBlock> BB1, BB2, BB3;914 BB1.reset(BasicBlock::Create(C));915 BB2.reset(BasicBlock::Create(C));916 BB3.reset(BasicBlock::Create(C));917 918 // We create block 0 after the others so that it gets destroyed first and919 // clears the uses of the other basic blocks.920 std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C));921 922 auto *Int32Ty = Type::getInt32Ty(C);923 924 SwitchInst *SI =925 SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 3, BB0.get());926 SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get());927 SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get());928 SI->addCase(ConstantInt::get(Int32Ty, 3), BB3.get());929 930 auto CI = SI->case_begin();931 ASSERT_NE(CI, SI->case_end());932 EXPECT_EQ(1, CI->getCaseValue()->getSExtValue());933 EXPECT_EQ(BB1.get(), CI->getCaseSuccessor());934 EXPECT_EQ(2, (CI + 1)->getCaseValue()->getSExtValue());935 EXPECT_EQ(BB2.get(), (CI + 1)->getCaseSuccessor());936 EXPECT_EQ(3, (CI + 2)->getCaseValue()->getSExtValue());937 EXPECT_EQ(BB3.get(), (CI + 2)->getCaseSuccessor());938 EXPECT_EQ(CI + 1, std::next(CI));939 EXPECT_EQ(CI + 2, std::next(CI, 2));940 EXPECT_EQ(CI + 3, std::next(CI, 3));941 EXPECT_EQ(SI->case_end(), CI + 3);942 EXPECT_EQ(0, CI - CI);943 EXPECT_EQ(1, (CI + 1) - CI);944 EXPECT_EQ(2, (CI + 2) - CI);945 EXPECT_EQ(3, SI->case_end() - CI);946 EXPECT_EQ(3, std::distance(CI, SI->case_end()));947 948 auto CCI = const_cast<const SwitchInst *>(SI)->case_begin();949 SwitchInst::ConstCaseIt CCE = SI->case_end();950 ASSERT_NE(CCI, SI->case_end());951 EXPECT_EQ(1, CCI->getCaseValue()->getSExtValue());952 EXPECT_EQ(BB1.get(), CCI->getCaseSuccessor());953 EXPECT_EQ(2, (CCI + 1)->getCaseValue()->getSExtValue());954 EXPECT_EQ(BB2.get(), (CCI + 1)->getCaseSuccessor());955 EXPECT_EQ(3, (CCI + 2)->getCaseValue()->getSExtValue());956 EXPECT_EQ(BB3.get(), (CCI + 2)->getCaseSuccessor());957 EXPECT_EQ(CCI + 1, std::next(CCI));958 EXPECT_EQ(CCI + 2, std::next(CCI, 2));959 EXPECT_EQ(CCI + 3, std::next(CCI, 3));960 EXPECT_EQ(CCE, CCI + 3);961 EXPECT_EQ(0, CCI - CCI);962 EXPECT_EQ(1, (CCI + 1) - CCI);963 EXPECT_EQ(2, (CCI + 2) - CCI);964 EXPECT_EQ(3, CCE - CCI);965 EXPECT_EQ(3, std::distance(CCI, CCE));966 967 // Make sure that the const iterator is compatible with a const auto ref.968 const auto &Handle = *CCI;969 EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue());970 EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor());971}972 973TEST(InstructionsTest, SwitchInstProfUpdateWrapper) {974 LLVMContext C;975 976 std::unique_ptr<BasicBlock> BB1, BB2, BB3;977 BB1.reset(BasicBlock::Create(C));978 BB2.reset(BasicBlock::Create(C));979 BB3.reset(BasicBlock::Create(C));980 981 // We create block 0 after the others so that it gets destroyed first and982 // clears the uses of the other basic blocks.983 std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C));984 985 auto *Int32Ty = Type::getInt32Ty(C);986 987 SwitchInst *SI =988 SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 4, BB0.get());989 SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get());990 SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get());991 SI->setMetadata(LLVMContext::MD_prof,992 MDBuilder(C).createBranchWeights({ 9, 1, 22 }));993 994 {995 SwitchInstProfUpdateWrapper SIW(*SI);996 EXPECT_EQ(*SIW.getSuccessorWeight(0), 9u);997 EXPECT_EQ(*SIW.getSuccessorWeight(1), 1u);998 EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);999 SIW.setSuccessorWeight(0, 99u);1000 SIW.setSuccessorWeight(1, 11u);1001 EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u);1002 EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u);1003 EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);1004 }1005 1006 { // Create another wrapper and check that the data persist.1007 SwitchInstProfUpdateWrapper SIW(*SI);1008 EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u);1009 EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u);1010 EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);1011 }1012}1013 1014TEST(InstructionsTest, CommuteShuffleMask) {1015 SmallVector<int, 16> Indices({-1, 0, 7});1016 ShuffleVectorInst::commuteShuffleMask(Indices, 4);1017 EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef<int>({-1, 4, 3})));1018}1019 1020TEST(InstructionsTest, ShuffleMaskQueries) {1021 // Create the elements for various constant vectors.1022 LLVMContext Ctx;1023 Type *Int32Ty = Type::getInt32Ty(Ctx);1024 Constant *CU = UndefValue::get(Int32Ty);1025 Constant *C0 = ConstantInt::get(Int32Ty, 0);1026 Constant *C1 = ConstantInt::get(Int32Ty, 1);1027 Constant *C2 = ConstantInt::get(Int32Ty, 2);1028 Constant *C3 = ConstantInt::get(Int32Ty, 3);1029 Constant *C4 = ConstantInt::get(Int32Ty, 4);1030 Constant *C5 = ConstantInt::get(Int32Ty, 5);1031 Constant *C6 = ConstantInt::get(Int32Ty, 6);1032 Constant *C7 = ConstantInt::get(Int32Ty, 7);1033 1034 Constant *Identity = ConstantVector::get({C0, CU, C2, C3, C4});1035 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(1036 Identity, cast<FixedVectorType>(Identity->getType())->getNumElements()));1037 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(1038 Identity,1039 cast<FixedVectorType>(Identity->getType())1040 ->getNumElements())); // identity is distinguished from select1041 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(1042 Identity, cast<FixedVectorType>(Identity->getType())->getNumElements()));1043 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(1044 Identity, cast<FixedVectorType>(Identity->getType())1045 ->getNumElements())); // identity is always single source1046 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(1047 Identity, cast<FixedVectorType>(Identity->getType())->getNumElements()));1048 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(1049 Identity, cast<FixedVectorType>(Identity->getType())->getNumElements()));1050 1051 Constant *Select = ConstantVector::get({CU, C1, C5});1052 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(1053 Select, cast<FixedVectorType>(Select->getType())->getNumElements()));1054 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(1055 Select, cast<FixedVectorType>(Select->getType())->getNumElements()));1056 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(1057 Select, cast<FixedVectorType>(Select->getType())->getNumElements()));1058 EXPECT_FALSE(ShuffleVectorInst::isSingleSourceMask(1059 Select, cast<FixedVectorType>(Select->getType())->getNumElements()));1060 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(1061 Select, cast<FixedVectorType>(Select->getType())->getNumElements()));1062 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(1063 Select, cast<FixedVectorType>(Select->getType())->getNumElements()));1064 1065 Constant *Reverse = ConstantVector::get({C3, C2, C1, CU});1066 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(1067 Reverse, cast<FixedVectorType>(Reverse->getType())->getNumElements()));1068 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(1069 Reverse, cast<FixedVectorType>(Reverse->getType())->getNumElements()));1070 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(1071 Reverse, cast<FixedVectorType>(Reverse->getType())->getNumElements()));1072 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(1073 Reverse, cast<FixedVectorType>(Reverse->getType())1074 ->getNumElements())); // reverse is always single source1075 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(1076 Reverse, cast<FixedVectorType>(Reverse->getType())->getNumElements()));1077 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(1078 Reverse, cast<FixedVectorType>(Reverse->getType())->getNumElements()));1079 1080 Constant *SingleSource = ConstantVector::get({C2, C2, C0, CU});1081 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(1082 SingleSource,1083 cast<FixedVectorType>(SingleSource->getType())->getNumElements()));1084 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(1085 SingleSource,1086 cast<FixedVectorType>(SingleSource->getType())->getNumElements()));1087 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(1088 SingleSource,1089 cast<FixedVectorType>(SingleSource->getType())->getNumElements()));1090 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(1091 SingleSource,1092 cast<FixedVectorType>(SingleSource->getType())->getNumElements()));1093 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(1094 SingleSource,1095 cast<FixedVectorType>(SingleSource->getType())->getNumElements()));1096 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(1097 SingleSource,1098 cast<FixedVectorType>(SingleSource->getType())->getNumElements()));1099 1100 Constant *ZeroEltSplat = ConstantVector::get({C0, C0, CU, C0});1101 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(1102 ZeroEltSplat,1103 cast<FixedVectorType>(ZeroEltSplat->getType())->getNumElements()));1104 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(1105 ZeroEltSplat,1106 cast<FixedVectorType>(ZeroEltSplat->getType())->getNumElements()));1107 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(1108 ZeroEltSplat,1109 cast<FixedVectorType>(ZeroEltSplat->getType())->getNumElements()));1110 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(1111 ZeroEltSplat, cast<FixedVectorType>(ZeroEltSplat->getType())1112 ->getNumElements())); // 0-splat is always single source1113 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(1114 ZeroEltSplat,1115 cast<FixedVectorType>(ZeroEltSplat->getType())->getNumElements()));1116 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(1117 ZeroEltSplat,1118 cast<FixedVectorType>(ZeroEltSplat->getType())->getNumElements()));1119 1120 Constant *Transpose = ConstantVector::get({C0, C4, C2, C6});1121 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(1122 Transpose,1123 cast<FixedVectorType>(Transpose->getType())->getNumElements()));1124 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(1125 Transpose,1126 cast<FixedVectorType>(Transpose->getType())->getNumElements()));1127 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(1128 Transpose,1129 cast<FixedVectorType>(Transpose->getType())->getNumElements()));1130 EXPECT_FALSE(ShuffleVectorInst::isSingleSourceMask(1131 Transpose,1132 cast<FixedVectorType>(Transpose->getType())->getNumElements()));1133 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(1134 Transpose,1135 cast<FixedVectorType>(Transpose->getType())->getNumElements()));1136 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(1137 Transpose,1138 cast<FixedVectorType>(Transpose->getType())->getNumElements()));1139 1140 // More tests to make sure the logic is/stays correct...1141 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(1142 ConstantVector::get({CU, C1, CU, C3}), 4));1143 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(1144 ConstantVector::get({C4, CU, C6, CU}), 4));1145 1146 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(1147 ConstantVector::get({C4, C1, C6, CU}), 4));1148 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(1149 ConstantVector::get({CU, C1, C6, C3}), 4));1150 1151 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(1152 ConstantVector::get({C7, C6, CU, C4}), 4));1153 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(1154 ConstantVector::get({C3, CU, C1, CU}), 4));1155 1156 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(1157 ConstantVector::get({C7, C5, CU, C7}), 4));1158 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(1159 ConstantVector::get({C3, C0, CU, C3}), 4));1160 1161 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(1162 ConstantVector::get({C4, CU, CU, C4}), 4));1163 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(1164 ConstantVector::get({CU, C0, CU, C0}), 4));1165 1166 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(1167 ConstantVector::get({C1, C5, C3, C7}), 4));1168 EXPECT_TRUE(1169 ShuffleVectorInst::isTransposeMask(ConstantVector::get({C1, C3}), 2));1170 1171 // Nothing special about the values here - just re-using inputs to reduce1172 // code.1173 Constant *V0 = ConstantVector::get({C0, C1, C2, C3});1174 Constant *V1 = ConstantVector::get({C3, C2, C1, C0});1175 1176 // Identity with undef elts.1177 ShuffleVectorInst *Id1 = new ShuffleVectorInst(V0, V1,1178 ConstantVector::get({C0, C1, CU, CU}));1179 EXPECT_TRUE(Id1->isIdentity());1180 EXPECT_FALSE(Id1->isIdentityWithPadding());1181 EXPECT_FALSE(Id1->isIdentityWithExtract());1182 EXPECT_FALSE(Id1->isConcat());1183 delete Id1;1184 1185 // Result has less elements than operands.1186 ShuffleVectorInst *Id2 = new ShuffleVectorInst(V0, V1,1187 ConstantVector::get({C0, C1, C2}));1188 EXPECT_FALSE(Id2->isIdentity());1189 EXPECT_FALSE(Id2->isIdentityWithPadding());1190 EXPECT_TRUE(Id2->isIdentityWithExtract());1191 EXPECT_FALSE(Id2->isConcat());1192 delete Id2;1193 1194 // Result has less elements than operands; choose from Op1.1195 ShuffleVectorInst *Id3 = new ShuffleVectorInst(V0, V1,1196 ConstantVector::get({C4, CU, C6}));1197 EXPECT_FALSE(Id3->isIdentity());1198 EXPECT_FALSE(Id3->isIdentityWithPadding());1199 EXPECT_TRUE(Id3->isIdentityWithExtract());1200 EXPECT_FALSE(Id3->isConcat());1201 delete Id3;1202 1203 // Result has less elements than operands; choose from Op0 and Op1 is not identity.1204 ShuffleVectorInst *Id4 = new ShuffleVectorInst(V0, V1,1205 ConstantVector::get({C4, C1, C6}));1206 EXPECT_FALSE(Id4->isIdentity());1207 EXPECT_FALSE(Id4->isIdentityWithPadding());1208 EXPECT_FALSE(Id4->isIdentityWithExtract());1209 EXPECT_FALSE(Id4->isConcat());1210 delete Id4;1211 1212 // Result has more elements than operands, and extra elements are undef.1213 ShuffleVectorInst *Id5 = new ShuffleVectorInst(V0, V1,1214 ConstantVector::get({CU, C1, C2, C3, CU, CU}));1215 EXPECT_FALSE(Id5->isIdentity());1216 EXPECT_TRUE(Id5->isIdentityWithPadding());1217 EXPECT_FALSE(Id5->isIdentityWithExtract());1218 EXPECT_FALSE(Id5->isConcat());1219 delete Id5;1220 1221 // Result has more elements than operands, and extra elements are undef; choose from Op1.1222 ShuffleVectorInst *Id6 = new ShuffleVectorInst(V0, V1,1223 ConstantVector::get({C4, C5, C6, CU, CU, CU}));1224 EXPECT_FALSE(Id6->isIdentity());1225 EXPECT_TRUE(Id6->isIdentityWithPadding());1226 EXPECT_FALSE(Id6->isIdentityWithExtract());1227 EXPECT_FALSE(Id6->isConcat());1228 delete Id6;1229 1230 // Result has more elements than operands, but extra elements are not undef.1231 ShuffleVectorInst *Id7 = new ShuffleVectorInst(V0, V1,1232 ConstantVector::get({C0, C1, C2, C3, CU, C1}));1233 EXPECT_FALSE(Id7->isIdentity());1234 EXPECT_FALSE(Id7->isIdentityWithPadding());1235 EXPECT_FALSE(Id7->isIdentityWithExtract());1236 EXPECT_FALSE(Id7->isConcat());1237 delete Id7;1238 1239 // Result has more elements than operands; choose from Op0 and Op1 is not identity.1240 ShuffleVectorInst *Id8 = new ShuffleVectorInst(V0, V1,1241 ConstantVector::get({C4, CU, C2, C3, CU, CU}));1242 EXPECT_FALSE(Id8->isIdentity());1243 EXPECT_FALSE(Id8->isIdentityWithPadding());1244 EXPECT_FALSE(Id8->isIdentityWithExtract());1245 EXPECT_FALSE(Id8->isConcat());1246 delete Id8;1247 1248 // Result has twice as many elements as operands; choose consecutively from Op0 and Op1 is concat.1249 ShuffleVectorInst *Id9 = new ShuffleVectorInst(V0, V1,1250 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6, C7}));1251 EXPECT_FALSE(Id9->isIdentity());1252 EXPECT_FALSE(Id9->isIdentityWithPadding());1253 EXPECT_FALSE(Id9->isIdentityWithExtract());1254 EXPECT_TRUE(Id9->isConcat());1255 delete Id9;1256 1257 // Result has less than twice as many elements as operands, so not a concat.1258 ShuffleVectorInst *Id10 = new ShuffleVectorInst(V0, V1,1259 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6}));1260 EXPECT_FALSE(Id10->isIdentity());1261 EXPECT_FALSE(Id10->isIdentityWithPadding());1262 EXPECT_FALSE(Id10->isIdentityWithExtract());1263 EXPECT_FALSE(Id10->isConcat());1264 delete Id10;1265 1266 // Result has more than twice as many elements as operands, so not a concat.1267 ShuffleVectorInst *Id11 = new ShuffleVectorInst(V0, V1,1268 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6, C7, CU}));1269 EXPECT_FALSE(Id11->isIdentity());1270 EXPECT_FALSE(Id11->isIdentityWithPadding());1271 EXPECT_FALSE(Id11->isIdentityWithExtract());1272 EXPECT_FALSE(Id11->isConcat());1273 delete Id11;1274 1275 // If an input is undef, it's not a concat.1276 // TODO: IdentityWithPadding should be true here even though the high mask values are not undef.1277 ShuffleVectorInst *Id12 = new ShuffleVectorInst(V0, ConstantVector::get({CU, CU, CU, CU}),1278 ConstantVector::get({C0, CU, C2, C3, CU, CU, C6, C7}));1279 EXPECT_FALSE(Id12->isIdentity());1280 EXPECT_FALSE(Id12->isIdentityWithPadding());1281 EXPECT_FALSE(Id12->isIdentityWithExtract());1282 EXPECT_FALSE(Id12->isConcat());1283 delete Id12;1284 1285 // Not possible to express shuffle mask for scalable vector for extract1286 // subvector.1287 Type *VScaleV4Int32Ty = ScalableVectorType::get(Int32Ty, 4);1288 ShuffleVectorInst *Id13 =1289 new ShuffleVectorInst(Constant::getAllOnesValue(VScaleV4Int32Ty),1290 UndefValue::get(VScaleV4Int32Ty),1291 Constant::getNullValue(VScaleV4Int32Ty));1292 int Index = 0;1293 EXPECT_FALSE(Id13->isExtractSubvectorMask(Index));1294 EXPECT_FALSE(Id13->changesLength());1295 EXPECT_FALSE(Id13->increasesLength());1296 delete Id13;1297 1298 // Result has twice as many operands.1299 Type *VScaleV2Int32Ty = ScalableVectorType::get(Int32Ty, 2);1300 ShuffleVectorInst *Id14 =1301 new ShuffleVectorInst(Constant::getAllOnesValue(VScaleV2Int32Ty),1302 UndefValue::get(VScaleV2Int32Ty),1303 Constant::getNullValue(VScaleV4Int32Ty));1304 EXPECT_TRUE(Id14->changesLength());1305 EXPECT_TRUE(Id14->increasesLength());1306 delete Id14;1307 1308 // Not possible to express these masks for scalable vectors, make sure we1309 // don't crash.1310 ShuffleVectorInst *Id15 =1311 new ShuffleVectorInst(Constant::getAllOnesValue(VScaleV2Int32Ty),1312 Constant::getNullValue(VScaleV2Int32Ty),1313 Constant::getNullValue(VScaleV2Int32Ty));1314 EXPECT_FALSE(Id15->isIdentityWithPadding());1315 EXPECT_FALSE(Id15->isIdentityWithExtract());1316 EXPECT_FALSE(Id15->isConcat());1317 delete Id15;1318}1319 1320TEST(InstructionsTest, ShuffleMaskIsReplicationMask) {1321 for (int ReplicationFactor : seq_inclusive(1, 8)) {1322 for (int VF : seq_inclusive(1, 8)) {1323 const auto ReplicatedMask = createReplicatedMask(ReplicationFactor, VF);1324 int GuessedReplicationFactor = -1, GuessedVF = -1;1325 EXPECT_TRUE(ShuffleVectorInst::isReplicationMask(1326 ReplicatedMask, GuessedReplicationFactor, GuessedVF));1327 EXPECT_EQ(GuessedReplicationFactor, ReplicationFactor);1328 EXPECT_EQ(GuessedVF, VF);1329 1330 for (int OpVF : seq_inclusive(VF, 2 * VF + 1)) {1331 LLVMContext Ctx;1332 Type *OpVFTy = FixedVectorType::get(IntegerType::getInt1Ty(Ctx), OpVF);1333 Value *Op = ConstantVector::getNullValue(OpVFTy);1334 ShuffleVectorInst *SVI = new ShuffleVectorInst(Op, Op, ReplicatedMask);1335 EXPECT_EQ(SVI->isReplicationMask(GuessedReplicationFactor, GuessedVF),1336 OpVF == VF);1337 delete SVI;1338 }1339 }1340 }1341}1342 1343TEST(InstructionsTest, ShuffleMaskIsReplicationMask_undef) {1344 for (int ReplicationFactor : seq_inclusive(1, 4)) {1345 for (int VF : seq_inclusive(1, 4)) {1346 const auto ReplicatedMask = createReplicatedMask(ReplicationFactor, VF);1347 int GuessedReplicationFactor = -1, GuessedVF = -1;1348 1349 // If we change some mask elements to undef, we should still match.1350 1351 SmallVector<SmallVector<bool>> ElementChoices(ReplicatedMask.size(),1352 {false, true});1353 1354 CombinationGenerator<bool, decltype(ElementChoices)::value_type,1355 /*variable_smallsize=*/4>1356 G(ElementChoices);1357 1358 G.generate([&](ArrayRef<bool> UndefOverrides) -> bool {1359 SmallVector<int> AdjustedMask;1360 AdjustedMask.reserve(ReplicatedMask.size());1361 for (auto I : zip(ReplicatedMask, UndefOverrides))1362 AdjustedMask.emplace_back(std::get<1>(I) ? -1 : std::get<0>(I));1363 assert(AdjustedMask.size() == ReplicatedMask.size() &&1364 "Size misprediction");1365 1366 EXPECT_TRUE(ShuffleVectorInst::isReplicationMask(1367 AdjustedMask, GuessedReplicationFactor, GuessedVF));1368 // Do not check GuessedReplicationFactor and GuessedVF,1369 // with enough undef's we may deduce a different tuple.1370 1371 return /*Abort=*/false;1372 });1373 }1374 }1375}1376 1377TEST(InstructionsTest, ShuffleMaskIsReplicationMask_Exhaustive_Correctness) {1378 for (int ShufMaskNumElts : seq_inclusive(1, 6)) {1379 SmallVector<int> PossibleShufMaskElts;1380 PossibleShufMaskElts.reserve(ShufMaskNumElts + 2);1381 for (int PossibleShufMaskElt : seq_inclusive(-1, ShufMaskNumElts))1382 PossibleShufMaskElts.emplace_back(PossibleShufMaskElt);1383 assert(PossibleShufMaskElts.size() == ShufMaskNumElts + 2U &&1384 "Size misprediction");1385 1386 SmallVector<SmallVector<int>> ElementChoices(ShufMaskNumElts,1387 PossibleShufMaskElts);1388 1389 CombinationGenerator<int, decltype(ElementChoices)::value_type,1390 /*variable_smallsize=*/4>1391 G(ElementChoices);1392 1393 G.generate([&](ArrayRef<int> Mask) -> bool {1394 int GuessedReplicationFactor = -1, GuessedVF = -1;1395 bool Match = ShuffleVectorInst::isReplicationMask(1396 Mask, GuessedReplicationFactor, GuessedVF);1397 if (!Match)1398 return /*Abort=*/false;1399 1400 const auto ActualMask =1401 createReplicatedMask(GuessedReplicationFactor, GuessedVF);1402 EXPECT_EQ(Mask.size(), ActualMask.size());1403 for (auto I : zip(Mask, ActualMask)) {1404 int Elt = std::get<0>(I);1405 int ActualElt = std::get<0>(I);1406 1407 if (Elt != -1) {1408 EXPECT_EQ(Elt, ActualElt);1409 }1410 }1411 1412 return /*Abort=*/false;1413 });1414 }1415}1416 1417TEST(InstructionsTest, GetSplat) {1418 // Create the elements for various constant vectors.1419 LLVMContext Ctx;1420 Type *Int32Ty = Type::getInt32Ty(Ctx);1421 Constant *CU = UndefValue::get(Int32Ty);1422 Constant *CP = PoisonValue::get(Int32Ty);1423 Constant *C0 = ConstantInt::get(Int32Ty, 0);1424 Constant *C1 = ConstantInt::get(Int32Ty, 1);1425 1426 Constant *Splat0 = ConstantVector::get({C0, C0, C0, C0});1427 Constant *Splat1 = ConstantVector::get({C1, C1, C1, C1 ,C1});1428 Constant *Splat0Undef = ConstantVector::get({C0, CU, C0, CU});1429 Constant *Splat1Undef = ConstantVector::get({CU, CU, C1, CU});1430 Constant *NotSplat = ConstantVector::get({C1, C1, C0, C1 ,C1});1431 Constant *NotSplatUndef = ConstantVector::get({CU, C1, CU, CU ,C0});1432 Constant *Splat0Poison = ConstantVector::get({C0, CP, C0, CP});1433 Constant *Splat1Poison = ConstantVector::get({CP, CP, C1, CP});1434 Constant *NotSplatPoison = ConstantVector::get({CP, C1, CP, CP, C0});1435 1436 // Default - undef/poison is not allowed.1437 EXPECT_EQ(Splat0->getSplatValue(), C0);1438 EXPECT_EQ(Splat1->getSplatValue(), C1);1439 EXPECT_EQ(Splat0Undef->getSplatValue(), nullptr);1440 EXPECT_EQ(Splat1Undef->getSplatValue(), nullptr);1441 EXPECT_EQ(Splat0Poison->getSplatValue(), nullptr);1442 EXPECT_EQ(Splat1Poison->getSplatValue(), nullptr);1443 EXPECT_EQ(NotSplat->getSplatValue(), nullptr);1444 EXPECT_EQ(NotSplatUndef->getSplatValue(), nullptr);1445 EXPECT_EQ(NotSplatPoison->getSplatValue(), nullptr);1446 1447 // Disallow poison explicitly.1448 EXPECT_EQ(Splat0->getSplatValue(false), C0);1449 EXPECT_EQ(Splat1->getSplatValue(false), C1);1450 EXPECT_EQ(Splat0Undef->getSplatValue(false), nullptr);1451 EXPECT_EQ(Splat1Undef->getSplatValue(false), nullptr);1452 EXPECT_EQ(Splat0Poison->getSplatValue(false), nullptr);1453 EXPECT_EQ(Splat1Poison->getSplatValue(false), nullptr);1454 EXPECT_EQ(NotSplat->getSplatValue(false), nullptr);1455 EXPECT_EQ(NotSplatUndef->getSplatValue(false), nullptr);1456 EXPECT_EQ(NotSplatPoison->getSplatValue(false), nullptr);1457 1458 // Allow poison but not undef.1459 EXPECT_EQ(Splat0->getSplatValue(true), C0);1460 EXPECT_EQ(Splat1->getSplatValue(true), C1);1461 EXPECT_EQ(Splat0Undef->getSplatValue(true), nullptr);1462 EXPECT_EQ(Splat1Undef->getSplatValue(true), nullptr);1463 EXPECT_EQ(Splat0Poison->getSplatValue(true), C0);1464 EXPECT_EQ(Splat1Poison->getSplatValue(true), C1);1465 EXPECT_EQ(NotSplat->getSplatValue(true), nullptr);1466 EXPECT_EQ(NotSplatUndef->getSplatValue(true), nullptr);1467 EXPECT_EQ(NotSplatPoison->getSplatValue(true), nullptr);1468}1469 1470TEST(InstructionsTest, SkipDebug) {1471 LLVMContext C;1472 std::unique_ptr<Module> M = parseIR(C,1473 R"(1474 declare void @llvm.dbg.value(metadata, metadata, metadata)1475 1476 define void @f() {1477 entry:1478 call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !131479 ret void1480 }1481 1482 !llvm.dbg.cu = !{!0}1483 !llvm.module.flags = !{!3, !4}1484 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1485 !1 = !DIFile(filename: "t2.c", directory: "foo")1486 !2 = !{}1487 !3 = !{i32 2, !"Dwarf Version", i32 4}1488 !4 = !{i32 2, !"Debug Info Version", i32 3}1489 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)1490 !9 = !DISubroutineType(types: !10)1491 !10 = !{null}1492 !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)1493 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)1494 !13 = !DILocation(line: 2, column: 7, scope: !8)1495 )");1496 ASSERT_TRUE(M);1497 Function *F = cast<Function>(M->getNamedValue("f"));1498 // This test wants to see dbg.values.1499 F->convertFromNewDbgValues();1500 BasicBlock &BB = F->front();1501 1502 // The first non-debug instruction is the terminator.1503 auto *Term = BB.getTerminator();1504 EXPECT_EQ(Term, BB.begin()->getNextNode());1505 EXPECT_EQ(Term->getIterator(), skipDebugIntrinsics(BB.begin()));1506 1507 // After the terminator, there are no non-debug instructions.1508 EXPECT_EQ(nullptr, Term->getNextNode());1509}1510 1511TEST(InstructionsTest, PhiMightNotBeFPMathOperator) {1512 LLVMContext Context;1513 IRBuilder<> Builder(Context);1514 MDBuilder MDHelper(Context);1515 Instruction *I = Builder.CreatePHI(Builder.getInt32Ty(), 0);1516 EXPECT_FALSE(isa<FPMathOperator>(I));1517 I->deleteValue();1518 Instruction *FP = Builder.CreatePHI(Builder.getDoubleTy(), 0);1519 EXPECT_TRUE(isa<FPMathOperator>(FP));1520 FP->deleteValue();1521}1522 1523TEST(InstructionsTest, FPCallIsFPMathOperator) {1524 LLVMContext C;1525 1526 Type *ITy = Type::getInt32Ty(C);1527 FunctionType *IFnTy = FunctionType::get(ITy, {});1528 PointerType *PtrTy = PointerType::getUnqual(C);1529 Value *ICallee = Constant::getNullValue(PtrTy);1530 std::unique_ptr<CallInst> ICall(CallInst::Create(IFnTy, ICallee, {}, ""));1531 EXPECT_FALSE(isa<FPMathOperator>(ICall));1532 1533 Type *VITy = FixedVectorType::get(ITy, 2);1534 FunctionType *VIFnTy = FunctionType::get(VITy, {});1535 Value *VICallee = Constant::getNullValue(PtrTy);1536 std::unique_ptr<CallInst> VICall(CallInst::Create(VIFnTy, VICallee, {}, ""));1537 EXPECT_FALSE(isa<FPMathOperator>(VICall));1538 1539 Type *AITy = ArrayType::get(ITy, 2);1540 FunctionType *AIFnTy = FunctionType::get(AITy, {});1541 Value *AICallee = Constant::getNullValue(PtrTy);1542 std::unique_ptr<CallInst> AICall(CallInst::Create(AIFnTy, AICallee, {}, ""));1543 EXPECT_FALSE(isa<FPMathOperator>(AICall));1544 1545 Type *FTy = Type::getFloatTy(C);1546 FunctionType *FFnTy = FunctionType::get(FTy, {});1547 Value *FCallee = Constant::getNullValue(PtrTy);1548 std::unique_ptr<CallInst> FCall(CallInst::Create(FFnTy, FCallee, {}, ""));1549 EXPECT_TRUE(isa<FPMathOperator>(FCall));1550 1551 Type *VFTy = FixedVectorType::get(FTy, 2);1552 FunctionType *VFFnTy = FunctionType::get(VFTy, {});1553 Value *VFCallee = Constant::getNullValue(PtrTy);1554 std::unique_ptr<CallInst> VFCall(CallInst::Create(VFFnTy, VFCallee, {}, ""));1555 EXPECT_TRUE(isa<FPMathOperator>(VFCall));1556 1557 Type *AFTy = ArrayType::get(FTy, 2);1558 FunctionType *AFFnTy = FunctionType::get(AFTy, {});1559 Value *AFCallee = Constant::getNullValue(PtrTy);1560 std::unique_ptr<CallInst> AFCall(CallInst::Create(AFFnTy, AFCallee, {}, ""));1561 EXPECT_TRUE(isa<FPMathOperator>(AFCall));1562 1563 Type *AVFTy = ArrayType::get(VFTy, 2);1564 FunctionType *AVFFnTy = FunctionType::get(AVFTy, {});1565 Value *AVFCallee = Constant::getNullValue(PtrTy);1566 std::unique_ptr<CallInst> AVFCall(1567 CallInst::Create(AVFFnTy, AVFCallee, {}, ""));1568 EXPECT_TRUE(isa<FPMathOperator>(AVFCall));1569 1570 Type *StructITy = StructType::get(ITy, ITy);1571 FunctionType *StructIFnTy = FunctionType::get(StructITy, {});1572 Value *StructICallee = Constant::getNullValue(PtrTy);1573 std::unique_ptr<CallInst> StructICall(1574 CallInst::Create(StructIFnTy, StructICallee, {}, ""));1575 EXPECT_FALSE(isa<FPMathOperator>(StructICall));1576 1577 Type *EmptyStructTy = StructType::get(C);1578 FunctionType *EmptyStructFnTy = FunctionType::get(EmptyStructTy, {});1579 Value *EmptyStructCallee = Constant::getNullValue(PtrTy);1580 std::unique_ptr<CallInst> EmptyStructCall(1581 CallInst::Create(EmptyStructFnTy, EmptyStructCallee, {}, ""));1582 EXPECT_FALSE(isa<FPMathOperator>(EmptyStructCall));1583 1584 Type *NamedStructFTy = StructType::create({FTy, FTy}, "AStruct");1585 FunctionType *NamedStructFFnTy = FunctionType::get(NamedStructFTy, {});1586 Value *NamedStructFCallee = Constant::getNullValue(PtrTy);1587 std::unique_ptr<CallInst> NamedStructFCall(1588 CallInst::Create(NamedStructFFnTy, NamedStructFCallee, {}, ""));1589 EXPECT_FALSE(isa<FPMathOperator>(NamedStructFCall));1590 1591 Type *MixedStructTy = StructType::get(FTy, ITy);1592 FunctionType *MixedStructFnTy = FunctionType::get(MixedStructTy, {});1593 Value *MixedStructCallee = Constant::getNullValue(PtrTy);1594 std::unique_ptr<CallInst> MixedStructCall(1595 CallInst::Create(MixedStructFnTy, MixedStructCallee, {}, ""));1596 EXPECT_FALSE(isa<FPMathOperator>(MixedStructCall));1597 1598 Type *StructFTy = StructType::get(FTy, FTy, FTy);1599 FunctionType *StructFFnTy = FunctionType::get(StructFTy, {});1600 Value *StructFCallee = Constant::getNullValue(PtrTy);1601 std::unique_ptr<CallInst> StructFCall(1602 CallInst::Create(StructFFnTy, StructFCallee, {}, ""));1603 EXPECT_TRUE(isa<FPMathOperator>(StructFCall));1604 1605 Type *StructVFTy = StructType::get(VFTy, VFTy, VFTy, VFTy);1606 FunctionType *StructVFFnTy = FunctionType::get(StructVFTy, {});1607 Value *StructVFCallee = Constant::getNullValue(PtrTy);1608 std::unique_ptr<CallInst> StructVFCall(1609 CallInst::Create(StructVFFnTy, StructVFCallee, {}, ""));1610 EXPECT_TRUE(isa<FPMathOperator>(StructVFCall));1611 1612 Type *NestedStructFTy = StructType::get(StructFTy, StructFTy, StructFTy);1613 FunctionType *NestedStructFFnTy = FunctionType::get(NestedStructFTy, {});1614 Value *NestedStructFCallee = Constant::getNullValue(PtrTy);1615 std::unique_ptr<CallInst> NestedStructFCall(1616 CallInst::Create(NestedStructFFnTy, NestedStructFCallee, {}, ""));1617 EXPECT_FALSE(isa<FPMathOperator>(NestedStructFCall));1618 1619 Type *AStructFTy = ArrayType::get(StructFTy, 5);1620 FunctionType *AStructFFnTy = FunctionType::get(AStructFTy, {});1621 Value *AStructFCallee = Constant::getNullValue(PtrTy);1622 std::unique_ptr<CallInst> AStructFCall(1623 CallInst::Create(AStructFFnTy, AStructFCallee, {}, ""));1624 EXPECT_FALSE(isa<FPMathOperator>(AStructFCall));1625}1626 1627TEST(InstructionsTest, FNegInstruction) {1628 LLVMContext Context;1629 Type *FltTy = Type::getFloatTy(Context);1630 Constant *One = ConstantFP::get(FltTy, 1.0);1631 BinaryOperator *FAdd = BinaryOperator::CreateFAdd(One, One);1632 FAdd->setHasNoNaNs(true);1633 UnaryOperator *FNeg = UnaryOperator::CreateFNegFMF(One, FAdd);1634 EXPECT_TRUE(FNeg->hasNoNaNs());1635 EXPECT_FALSE(FNeg->hasNoInfs());1636 EXPECT_FALSE(FNeg->hasNoSignedZeros());1637 EXPECT_FALSE(FNeg->hasAllowReciprocal());1638 EXPECT_FALSE(FNeg->hasAllowContract());1639 EXPECT_FALSE(FNeg->hasAllowReassoc());1640 EXPECT_FALSE(FNeg->hasApproxFunc());1641 FAdd->deleteValue();1642 FNeg->deleteValue();1643}1644 1645TEST(InstructionsTest, CallBrInstruction) {1646 LLVMContext Context;1647 std::unique_ptr<Module> M = parseIR(Context, R"(1648define void @foo() {1649entry:1650 callbr void asm sideeffect "// XXX: ${0:l}", "!i"()1651 to label %land.rhs.i [label %branch_test.exit]1652 1653land.rhs.i:1654 br label %branch_test.exit1655 1656branch_test.exit:1657 %0 = phi i1 [ true, %entry ], [ false, %land.rhs.i ]1658 br i1 %0, label %if.end, label %if.then1659 1660if.then:1661 ret void1662 1663if.end:1664 ret void1665}1666)");1667 Function *Foo = M->getFunction("foo");1668 auto BBs = Foo->begin();1669 CallBrInst &CBI = cast<CallBrInst>(BBs->front());1670 ++BBs;1671 ++BBs;1672 BasicBlock &BranchTestExit = *BBs;1673 ++BBs;1674 BasicBlock &IfThen = *BBs;1675 1676 // Test that setting the first indirect destination of callbr updates the dest1677 EXPECT_EQ(&BranchTestExit, CBI.getIndirectDest(0));1678 CBI.setIndirectDest(0, &IfThen);1679 EXPECT_EQ(&IfThen, CBI.getIndirectDest(0));1680}1681 1682TEST(InstructionsTest, UnaryOperator) {1683 LLVMContext Context;1684 IRBuilder<> Builder(Context);1685 Instruction *I = Builder.CreatePHI(Builder.getDoubleTy(), 0);1686 Value *F = Builder.CreateFNeg(I);1687 1688 EXPECT_TRUE(isa<Value>(F));1689 EXPECT_TRUE(isa<Instruction>(F));1690 EXPECT_TRUE(isa<UnaryInstruction>(F));1691 EXPECT_TRUE(isa<UnaryOperator>(F));1692 EXPECT_FALSE(isa<BinaryOperator>(F));1693 1694 F->deleteValue();1695 I->deleteValue();1696}1697 1698TEST(InstructionsTest, DropLocation) {1699 LLVMContext C;1700 std::unique_ptr<Module> M = parseIR(C,1701 R"(1702 declare void @callee()1703 1704 define void @no_parent_scope() {1705 call void @callee() ; I1: Call with no location.1706 call void @callee(), !dbg !11 ; I2: Call with location.1707 ret void, !dbg !11 ; I3: Non-call with location.1708 }1709 1710 define void @with_parent_scope() !dbg !8 {1711 call void @callee() ; I1: Call with no location.1712 call void @callee(), !dbg !11 ; I2: Call with location.1713 ret void, !dbg !11 ; I3: Non-call with location.1714 }1715 1716 !llvm.dbg.cu = !{!0}1717 !llvm.module.flags = !{!3, !4}1718 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)1719 !1 = !DIFile(filename: "t2.c", directory: "foo")1720 !2 = !{}1721 !3 = !{i32 2, !"Dwarf Version", i32 4}1722 !4 = !{i32 2, !"Debug Info Version", i32 3}1723 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)1724 !9 = !DISubroutineType(types: !10)1725 !10 = !{null}1726 !11 = !DILocation(line: 2, column: 7, scope: !8, inlinedAt: !12)1727 !12 = !DILocation(line: 3, column: 8, scope: !8)1728 )");1729 ASSERT_TRUE(M);1730 1731 {1732 Function *NoParentScopeF =1733 cast<Function>(M->getNamedValue("no_parent_scope"));1734 BasicBlock &BB = NoParentScopeF->front();1735 1736 auto *I1 = &*BB.getFirstNonPHIIt();1737 auto *I2 = I1->getNextNode();1738 auto *I3 = BB.getTerminator();1739 1740 EXPECT_EQ(I1->getDebugLoc(), DebugLoc());1741 I1->dropLocation();1742 EXPECT_EQ(I1->getDebugLoc(), DebugLoc());1743 1744 EXPECT_EQ(I2->getDebugLoc().getLine(), 2U);1745 I2->dropLocation();1746 EXPECT_EQ(I1->getDebugLoc(), DebugLoc());1747 1748 EXPECT_EQ(I3->getDebugLoc().getLine(), 2U);1749 I3->dropLocation();1750 EXPECT_EQ(I3->getDebugLoc(), DebugLoc());1751 }1752 1753 {1754 Function *WithParentScopeF =1755 cast<Function>(M->getNamedValue("with_parent_scope"));1756 BasicBlock &BB = WithParentScopeF->front();1757 1758 auto *I2 = BB.getFirstNonPHIIt()->getNextNode();1759 1760 MDNode *Scope = cast<MDNode>(WithParentScopeF->getSubprogram());1761 EXPECT_EQ(I2->getDebugLoc().getLine(), 2U);1762 I2->dropLocation();1763 EXPECT_EQ(I2->getDebugLoc().getLine(), 0U);1764 EXPECT_EQ(I2->getDebugLoc().getScope(), Scope);1765 EXPECT_EQ(I2->getDebugLoc().getInlinedAt(), nullptr);1766 }1767}1768 1769TEST(InstructionsTest, BranchWeightOverflow) {1770 LLVMContext C;1771 std::unique_ptr<Module> M = parseIR(C,1772 R"(1773 declare void @callee()1774 1775 define void @caller() {1776 call void @callee(), !prof !11777 ret void1778 }1779 1780 !1 = !{!"branch_weights", i32 20000}1781 )");1782 ASSERT_TRUE(M);1783 CallInst *CI =1784 cast<CallInst>(&M->getFunction("caller")->getEntryBlock().front());1785 uint64_t ProfWeight;1786 CI->extractProfTotalWeight(ProfWeight);1787 ASSERT_EQ(ProfWeight, 20000U);1788 CI->updateProfWeight(10000000, 1);1789 CI->extractProfTotalWeight(ProfWeight);1790 ASSERT_EQ(ProfWeight, UINT32_MAX);1791}1792 1793TEST(InstructionsTest, FreezeInst) {1794 LLVMContext C;1795 std::unique_ptr<Module> M = parseIR(C,1796 R"(1797 define void @foo(i8 %arg) {1798 freeze i8 %arg1799 ret void1800 }1801 )");1802 ASSERT_TRUE(M);1803 Value *FI = &M->getFunction("foo")->getEntryBlock().front();1804 EXPECT_TRUE(isa<UnaryInstruction>(FI));1805}1806 1807TEST(InstructionsTest, AllocaInst) {1808 LLVMContext Ctx;1809 std::unique_ptr<Module> M = parseIR(Ctx, R"(1810 %T = type { i64, [3 x i32]}1811 define void @f(i32 %n) {1812 entry:1813 %A = alloca i32, i32 11814 %B = alloca i32, i32 41815 %C = alloca i32, i32 %n1816 %D = alloca double1817 %E = alloca <vscale x 8 x double>1818 %F = alloca [2 x half]1819 %G = alloca [2 x [3 x i128]]1820 %H = alloca %T1821 %I = alloca i32, i64 92233720368547758071822 ret void1823 }1824 )");1825 const DataLayout &DL = M->getDataLayout();1826 ASSERT_TRUE(M);1827 Function *Fun = cast<Function>(M->getNamedValue("f"));1828 BasicBlock &BB = Fun->front();1829 auto It = BB.begin();1830 AllocaInst &A = cast<AllocaInst>(*It++);1831 AllocaInst &B = cast<AllocaInst>(*It++);1832 AllocaInst &C = cast<AllocaInst>(*It++);1833 AllocaInst &D = cast<AllocaInst>(*It++);1834 AllocaInst &E = cast<AllocaInst>(*It++);1835 AllocaInst &F = cast<AllocaInst>(*It++);1836 AllocaInst &G = cast<AllocaInst>(*It++);1837 AllocaInst &H = cast<AllocaInst>(*It++);1838 AllocaInst &I = cast<AllocaInst>(*It++);1839 EXPECT_EQ(A.getAllocationSizeInBits(DL), TypeSize::getFixed(32));1840 EXPECT_EQ(B.getAllocationSizeInBits(DL), TypeSize::getFixed(128));1841 EXPECT_FALSE(C.getAllocationSizeInBits(DL));1842 EXPECT_EQ(DL.getTypeSizeInBits(D.getAllocatedType()), TypeSize::getFixed(64));1843 EXPECT_EQ(D.getAllocationSizeInBits(DL), TypeSize::getFixed(64));1844 EXPECT_EQ(E.getAllocationSizeInBits(DL), TypeSize::getScalable(512));1845 EXPECT_EQ(F.getAllocationSizeInBits(DL), TypeSize::getFixed(32));1846 EXPECT_EQ(G.getAllocationSizeInBits(DL), TypeSize::getFixed(768));1847 EXPECT_EQ(H.getAllocationSizeInBits(DL), TypeSize::getFixed(160));1848 EXPECT_FALSE(I.getAllocationSizeInBits(DL));1849}1850 1851TEST(InstructionsTest, InsertAtBegin) {1852 LLVMContext Ctx;1853 std::unique_ptr<Module> M = parseIR(Ctx, R"(1854 define void @f(i32 %a, i32 %b) {1855 entry:1856 ret void1857 }1858)");1859 Function *F = &*M->begin();1860 Argument *ArgA = F->getArg(0);1861 Argument *ArgB = F->getArg(1);1862 BasicBlock *BB = &*F->begin();1863 Instruction *Ret = &*BB->begin();1864 Instruction *I = BinaryOperator::CreateAdd(ArgA, ArgB);1865 auto It = I->insertInto(BB, BB->begin());1866 EXPECT_EQ(&*It, I);1867 EXPECT_EQ(I->getNextNode(), Ret);1868}1869 1870TEST(InstructionsTest, InsertAtEnd) {1871 LLVMContext Ctx;1872 std::unique_ptr<Module> M = parseIR(Ctx, R"(1873 define void @f(i32 %a, i32 %b) {1874 entry:1875 ret void1876 }1877)");1878 Function *F = &*M->begin();1879 Argument *ArgA = F->getArg(0);1880 Argument *ArgB = F->getArg(1);1881 BasicBlock *BB = &*F->begin();1882 Instruction *Ret = &*BB->begin();1883 Instruction *I = BinaryOperator::CreateAdd(ArgA, ArgB);1884 auto It = I->insertInto(BB, BB->end());1885 EXPECT_EQ(&*It, I);1886 EXPECT_EQ(Ret->getNextNode(), I);1887}1888 1889TEST(InstructionsTest, AtomicSyncscope) {1890 LLVMContext Ctx;1891 1892 Module M("Mod", Ctx);1893 FunctionType *FT = FunctionType::get(Type::getVoidTy(Ctx), {}, false);1894 Function *F = Function::Create(FT, Function::ExternalLinkage, "Fun", M);1895 BasicBlock *BB = BasicBlock::Create(Ctx, "Entry", F);1896 IRBuilder<> Builder(BB);1897 1898 // SyncScope-variants of LLVM C IRBuilder APIs are tested by llvm-c-test,1899 // so cover the old versions (with a SingleThreaded argument) here.1900 Value *Ptr = ConstantPointerNull::get(Builder.getPtrTy());1901 Value *Val = ConstantInt::get(Type::getInt32Ty(Ctx), 0);1902 1903 // fence1904 LLVMValueRef Fence = LLVMBuildFence(1905 wrap(&Builder), LLVMAtomicOrderingSequentiallyConsistent, 0, "");1906 EXPECT_FALSE(LLVMIsAtomicSingleThread(Fence));1907 Fence = LLVMBuildFence(wrap(&Builder),1908 LLVMAtomicOrderingSequentiallyConsistent, 1, "");1909 EXPECT_TRUE(LLVMIsAtomicSingleThread(Fence));1910 1911 // atomicrmw1912 LLVMValueRef AtomicRMW = LLVMBuildAtomicRMW(1913 wrap(&Builder), LLVMAtomicRMWBinOpXchg, wrap(Ptr), wrap(Val),1914 LLVMAtomicOrderingSequentiallyConsistent, 0);1915 EXPECT_FALSE(LLVMIsAtomicSingleThread(AtomicRMW));1916 AtomicRMW = LLVMBuildAtomicRMW(wrap(&Builder), LLVMAtomicRMWBinOpXchg,1917 wrap(Ptr), wrap(Val),1918 LLVMAtomicOrderingSequentiallyConsistent, 1);1919 EXPECT_TRUE(LLVMIsAtomicSingleThread(AtomicRMW));1920 1921 // cmpxchg1922 LLVMValueRef CmpXchg =1923 LLVMBuildAtomicCmpXchg(wrap(&Builder), wrap(Ptr), wrap(Val), wrap(Val),1924 LLVMAtomicOrderingSequentiallyConsistent,1925 LLVMAtomicOrderingSequentiallyConsistent, 0);1926 EXPECT_FALSE(LLVMIsAtomicSingleThread(CmpXchg));1927 CmpXchg =1928 LLVMBuildAtomicCmpXchg(wrap(&Builder), wrap(Ptr), wrap(Val), wrap(Val),1929 LLVMAtomicOrderingSequentiallyConsistent,1930 LLVMAtomicOrderingSequentiallyConsistent, 1);1931 EXPECT_TRUE(LLVMIsAtomicSingleThread(CmpXchg));1932}1933 1934TEST(InstructionsTest, CmpPredicate) {1935 CmpPredicate P0(CmpInst::ICMP_ULE, false), P1(CmpInst::ICMP_ULE, true),1936 P2(CmpInst::ICMP_SLE, false), P3(CmpInst::ICMP_SLT, false);1937 CmpPredicate Q0 = P0, Q1 = P1, Q2 = P2;1938 CmpInst::Predicate R0 = P0, R1 = P1, R2 = P2;1939 1940 EXPECT_EQ(*CmpPredicate::getMatching(P0, P1), CmpInst::ICMP_ULE);1941 EXPECT_EQ(CmpPredicate::getMatching(P0, P1)->hasSameSign(), false);1942 EXPECT_EQ(*CmpPredicate::getMatching(P1, P1), CmpInst::ICMP_ULE);1943 EXPECT_EQ(CmpPredicate::getMatching(P1, P1)->hasSameSign(), true);1944 EXPECT_EQ(CmpPredicate::getMatching(P0, P2), std::nullopt);1945 EXPECT_EQ(*CmpPredicate::getMatching(P1, P2), CmpInst::ICMP_SLE);1946 EXPECT_EQ(CmpPredicate::getMatching(P1, P2)->hasSameSign(), false);1947 EXPECT_EQ(CmpPredicate::getMatching(P1, P3), std::nullopt);1948 EXPECT_EQ(CmpPredicate::getMatching(P1, CmpInst::FCMP_ULE), std::nullopt);1949 EXPECT_FALSE(Q0.hasSameSign());1950 EXPECT_TRUE(Q1.hasSameSign());1951 EXPECT_FALSE(Q2.hasSameSign());1952 EXPECT_EQ(P0, R0);1953 EXPECT_EQ(P1, R1);1954 EXPECT_EQ(P2, R2);1955}1956 1957TEST(InstructionsTest, StripAndAccumulateConstantOffset) {1958 LLVMContext C;1959 DataLayout DL;1960 std::unique_ptr<Module> M = parseIR(C, R"(1961 define void @foo(ptr %ptr, i64 %offset) {1962 %gep = getelementptr inbounds [1 x i8], ptr %ptr, i64 4, i64 %offset1963 ret void1964 })");1965 ASSERT_TRUE(M);1966 Value *GEP = &M->getFunction("foo")->getEntryBlock().front();1967 APInt Offset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);1968 Value *Stripped = GEP->stripAndAccumulateConstantOffsets(1969 DL, Offset, /*AllowNonInBounds=*/true);1970 EXPECT_EQ(Stripped, GEP);1971 EXPECT_TRUE(Offset.isZero());1972}1973 1974} // end anonymous namespace1975} // end namespace llvm1976