blob: b7341603cf690b14ee088aeb5afdd19bdf58ae62 [file] [log] [blame]
Dan Gohmanab37f502010-08-02 23:49:30 +00001//===- 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