ScalarEvolutionTest.cpp revision 2280ebd61416b73d0b6137f275b25af82e268d1f
1//===- ScalarEvolutionsTest.cpp - ScalarEvolution unit tests --------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <llvm/Analysis/ScalarEvolutionExpressions.h>
11#include <llvm/GlobalVariable.h>
12#include <llvm/Constants.h>
13#include <llvm/LLVMContext.h>
14#include <llvm/Module.h>
15#include <llvm/PassManager.h>
16#include "gtest/gtest.h"
17
18namespace llvm {
19namespace {
20
21TEST(ScalarEvolutionsTest, SCEVUnknownRAUW) {
22  LLVMContext Context;
23  Module M("world", Context);
24
25  const FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
26                                              std::vector<const Type *>(), false);
27  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
28  BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
29  ReturnInst::Create(Context, 0, BB);
30
31  const Type *Ty = Type::getInt1Ty(Context);
32  Constant *Init = Constant::getNullValue(Ty);
33  Value *V0 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V0");
34  Value *V1 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V1");
35  Value *V2 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V2");
36
37  // Create a ScalarEvolution and "run" it so that it gets initialized.
38  PassManager PM;
39  ScalarEvolution &SE = *new ScalarEvolution();
40  PM.add(&SE);
41  PM.run(M);
42
43  const SCEV *S0 = SE.getSCEV(V0);
44  const SCEV *S1 = SE.getSCEV(V1);
45  const SCEV *S2 = SE.getSCEV(V2);
46
47  const SCEV *P0 = SE.getAddExpr(S0, S0);
48  const SCEV *P1 = SE.getAddExpr(S1, S1);
49  const SCEV *P2 = SE.getAddExpr(S2, S2);
50
51  const SCEVMulExpr *M0 = cast<SCEVMulExpr>(P0);
52  const SCEVMulExpr *M1 = cast<SCEVMulExpr>(P1);
53  const SCEVMulExpr *M2 = cast<SCEVMulExpr>(P2);
54
55  EXPECT_EQ(cast<SCEVConstant>(M0->getOperand(0))->getValue()->getZExtValue(),
56            2u);
57  EXPECT_EQ(cast<SCEVConstant>(M1->getOperand(0))->getValue()->getZExtValue(),
58            2u);
59  EXPECT_EQ(cast<SCEVConstant>(M2->getOperand(0))->getValue()->getZExtValue(),
60            2u);
61
62  // Before the RAUWs, these are all pointing to separate values.
63  EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
64  EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V1);
65  EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V2);
66
67  // Do some RAUWs.
68  V2->replaceAllUsesWith(V1);
69  V1->replaceAllUsesWith(V0);
70
71  // After the RAUWs, these should all be pointing to V0.
72  EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
73  EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V0);
74  EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V0);
75
76  // Manually clean up, since we allocated new SCEV objects after the
77  // pass was finished.
78  SE.releaseMemory();
79}
80
81}  // end anonymous namespace
82}  // end namespace llvm
83