Second attempt at de-constifying LLVM Types in FunctionType::get(),
[oota-llvm.git] / unittests / Analysis / ScalarEvolutionTest.cpp
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
18 namespace llvm {
19 namespace {
20
21 TEST(ScalarEvolutionsTest, SCEVUnknownRAUW) {
22   LLVMContext Context;
23   Module M("world", Context);
24
25   const FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
26                                               std::vector<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