blob: eded23e84305ff7d92ee6c10fc2e636eba4e6ce7 [file] [log] [blame]
Dan Gohman7cac9572010-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
Wei Mi3076cc32016-09-15 04:06:44 +000010#include "llvm/Analysis/ScalarEvolutionExpander.h"
Craig Topperbc40d7e2012-09-15 18:45:38 +000011#include "llvm/Analysis/ScalarEvolutionExpressions.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000012#include "llvm/Analysis/LoopInfo.h"
13#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000014#include "llvm/ADT/SmallVector.h"
Craig Topperbc40d7e2012-09-15 18:45:38 +000015#include "llvm/Analysis/LoopInfo.h"
Sanjoy Das507dd402016-10-18 17:45:16 +000016#include "llvm/AsmParser/Parser.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000017#include "llvm/IR/Constants.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000018#include "llvm/IR/Dominators.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000019#include "llvm/IR/GlobalVariable.h"
Sanjoy Das507dd402016-10-18 17:45:16 +000020#include "llvm/IR/InstIterator.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000021#include "llvm/IR/LLVMContext.h"
22#include "llvm/IR/Module.h"
Chandler Carruth30d69c22015-02-13 10:01:29 +000023#include "llvm/IR/LegacyPassManager.h"
Sanjoy Das507dd402016-10-18 17:45:16 +000024#include "llvm/IR/Verifier.h"
25#include "llvm/Support/SourceMgr.h"
Dan Gohman7cac9572010-08-02 23:49:30 +000026#include "gtest/gtest.h"
27
28namespace llvm {
29namespace {
30
Nick Lewycky287682e2011-10-04 06:51:26 +000031// We use this fixture to ensure that we clean up ScalarEvolution before
32// deleting the PassManager.
33class ScalarEvolutionsTest : public testing::Test {
34protected:
Dan Gohman7cac9572010-08-02 23:49:30 +000035 LLVMContext Context;
Nick Lewycky287682e2011-10-04 06:51:26 +000036 Module M;
Chandler Carruth2f1fd162015-08-17 02:08:17 +000037 TargetLibraryInfoImpl TLII;
38 TargetLibraryInfo TLI;
39
Chandler Carruth2f1fd162015-08-17 02:08:17 +000040 std::unique_ptr<DominatorTree> DT;
41 std::unique_ptr<LoopInfo> LI;
42
43 ScalarEvolutionsTest() : M("", Context), TLII(), TLI(TLII) {}
44
45 ScalarEvolution buildSE(Function &F) {
Chandler Carruth2f1fd162015-08-17 02:08:17 +000046 DT.reset(new DominatorTree(F));
47 LI.reset(new LoopInfo(*DT));
Hal Finkel3ca4a6b2016-12-15 03:02:15 +000048 return ScalarEvolution(F, TLI, *DT, *LI);
Chandler Carruth2f1fd162015-08-17 02:08:17 +000049 }
Sanjoy Das6764b9a2016-11-10 07:56:05 +000050
Sanjoy Dasb1227db2016-12-12 14:57:11 +000051 void runWithFunctionAndSE(
52 Module &M, StringRef FuncName,
53 function_ref<void(Function &F, ScalarEvolution &SE)> Test) {
Reid Kleckner30422ee2016-12-12 18:52:32 +000054 auto *F = M.getFunction(FuncName);
55 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
56 ScalarEvolution SE = buildSE(*F);
57 Test(*F, SE);
Sanjoy Das6764b9a2016-11-10 07:56:05 +000058 }
Nick Lewycky287682e2011-10-04 06:51:26 +000059};
Dan Gohman7cac9572010-08-02 23:49:30 +000060
Nick Lewycky287682e2011-10-04 06:51:26 +000061TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
Chris Lattner229907c2011-07-18 04:54:35 +000062 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
Jay Foadb804a2b2011-07-12 14:06:48 +000063 std::vector<Type *>(), false);
Dan Gohman7cac9572010-08-02 23:49:30 +000064 Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
65 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
Craig Topper66f09ad2014-06-08 22:29:17 +000066 ReturnInst::Create(Context, nullptr, BB);
Dan Gohman7cac9572010-08-02 23:49:30 +000067
Chris Lattner229907c2011-07-18 04:54:35 +000068 Type *Ty = Type::getInt1Ty(Context);
Dan Gohman7cac9572010-08-02 23:49:30 +000069 Constant *Init = Constant::getNullValue(Ty);
70 Value *V0 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V0");
71 Value *V1 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V1");
72 Value *V2 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V2");
73
Chandler Carruth2f1fd162015-08-17 02:08:17 +000074 ScalarEvolution SE = buildSE(*F);
Dan Gohman7cac9572010-08-02 23:49:30 +000075
76 const SCEV *S0 = SE.getSCEV(V0);
77 const SCEV *S1 = SE.getSCEV(V1);
78 const SCEV *S2 = SE.getSCEV(V2);
79
80 const SCEV *P0 = SE.getAddExpr(S0, S0);
81 const SCEV *P1 = SE.getAddExpr(S1, S1);
82 const SCEV *P2 = SE.getAddExpr(S2, S2);
83
84 const SCEVMulExpr *M0 = cast<SCEVMulExpr>(P0);
85 const SCEVMulExpr *M1 = cast<SCEVMulExpr>(P1);
86 const SCEVMulExpr *M2 = cast<SCEVMulExpr>(P2);
87
88 EXPECT_EQ(cast<SCEVConstant>(M0->getOperand(0))->getValue()->getZExtValue(),
89 2u);
90 EXPECT_EQ(cast<SCEVConstant>(M1->getOperand(0))->getValue()->getZExtValue(),
91 2u);
92 EXPECT_EQ(cast<SCEVConstant>(M2->getOperand(0))->getValue()->getZExtValue(),
93 2u);
94
95 // Before the RAUWs, these are all pointing to separate values.
96 EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
97 EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V1);
98 EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V2);
99
100 // Do some RAUWs.
101 V2->replaceAllUsesWith(V1);
102 V1->replaceAllUsesWith(V0);
103
104 // After the RAUWs, these should all be pointing to V0.
105 EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
106 EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V0);
107 EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V0);
Nick Lewycky287682e2011-10-04 06:51:26 +0000108}
Dan Gohman7cac9572010-08-02 23:49:30 +0000109
Nick Lewycky287682e2011-10-04 06:51:26 +0000110TEST_F(ScalarEvolutionsTest, SCEVMultiplyAddRecs) {
111 Type *Ty = Type::getInt32Ty(Context);
112 SmallVector<Type *, 10> Types;
113 Types.append(10, Ty);
114 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
115 Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
116 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
Craig Topper66f09ad2014-06-08 22:29:17 +0000117 ReturnInst::Create(Context, nullptr, BB);
Nick Lewycky287682e2011-10-04 06:51:26 +0000118
Chandler Carruth2f1fd162015-08-17 02:08:17 +0000119 ScalarEvolution SE = buildSE(*F);
Nick Lewycky287682e2011-10-04 06:51:26 +0000120
121 // It's possible to produce an empty loop through the default constructor,
122 // but you can't add any blocks to it without a LoopInfo pass.
123 Loop L;
124 const_cast<std::vector<BasicBlock*>&>(L.getBlocks()).push_back(BB);
125
126 Function::arg_iterator AI = F->arg_begin();
127 SmallVector<const SCEV *, 5> A;
128 A.push_back(SE.getSCEV(&*AI++));
129 A.push_back(SE.getSCEV(&*AI++));
130 A.push_back(SE.getSCEV(&*AI++));
131 A.push_back(SE.getSCEV(&*AI++));
132 A.push_back(SE.getSCEV(&*AI++));
133 const SCEV *A_rec = SE.getAddRecExpr(A, &L, SCEV::FlagAnyWrap);
134
135 SmallVector<const SCEV *, 5> B;
136 B.push_back(SE.getSCEV(&*AI++));
137 B.push_back(SE.getSCEV(&*AI++));
138 B.push_back(SE.getSCEV(&*AI++));
139 B.push_back(SE.getSCEV(&*AI++));
140 B.push_back(SE.getSCEV(&*AI++));
141 const SCEV *B_rec = SE.getAddRecExpr(B, &L, SCEV::FlagAnyWrap);
142
143 /* Spot check that we perform this transformation:
144 {A0,+,A1,+,A2,+,A3,+,A4} * {B0,+,B1,+,B2,+,B3,+,B4} =
145 {A0*B0,+,
146 A1*B0 + A0*B1 + A1*B1,+,
147 A2*B0 + 2A1*B1 + A0*B2 + 2A2*B1 + 2A1*B2 + A2*B2,+,
148 A3*B0 + 3A2*B1 + 3A1*B2 + A0*B3 + 3A3*B1 + 6A2*B2 + 3A1*B3 + 3A3*B2 +
149 3A2*B3 + A3*B3,+,
150 A4*B0 + 4A3*B1 + 6A2*B2 + 4A1*B3 + A0*B4 + 4A4*B1 + 12A3*B2 + 12A2*B3 +
151 4A1*B4 + 6A4*B2 + 12A3*B3 + 6A2*B4 + 4A4*B3 + 4A3*B4 + A4*B4,+,
152 5A4*B1 + 10A3*B2 + 10A2*B3 + 5A1*B4 + 20A4*B2 + 30A3*B3 + 20A2*B4 +
153 30A4*B3 + 30A3*B4 + 20A4*B4,+,
154 15A4*B2 + 20A3*B3 + 15A2*B4 + 60A4*B3 + 60A3*B4 + 90A4*B4,+,
155 35A4*B3 + 35A3*B4 + 140A4*B4,+,
156 70A4*B4}
157 */
158
159 const SCEVAddRecExpr *Product =
160 dyn_cast<SCEVAddRecExpr>(SE.getMulExpr(A_rec, B_rec));
161 ASSERT_TRUE(Product);
162 ASSERT_EQ(Product->getNumOperands(), 9u);
163
164 SmallVector<const SCEV *, 16> Sum;
165 Sum.push_back(SE.getMulExpr(A[0], B[0]));
166 EXPECT_EQ(Product->getOperand(0), SE.getAddExpr(Sum));
167 Sum.clear();
168
169 // SCEV produces different an equal but different expression for these.
170 // Re-enable when PR11052 is fixed.
171#if 0
172 Sum.push_back(SE.getMulExpr(A[1], B[0]));
173 Sum.push_back(SE.getMulExpr(A[0], B[1]));
174 Sum.push_back(SE.getMulExpr(A[1], B[1]));
175 EXPECT_EQ(Product->getOperand(1), SE.getAddExpr(Sum));
176 Sum.clear();
177
178 Sum.push_back(SE.getMulExpr(A[2], B[0]));
179 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[1], B[1]));
180 Sum.push_back(SE.getMulExpr(A[0], B[2]));
181 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[2], B[1]));
182 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[1], B[2]));
183 Sum.push_back(SE.getMulExpr(A[2], B[2]));
184 EXPECT_EQ(Product->getOperand(2), SE.getAddExpr(Sum));
185 Sum.clear();
186
187 Sum.push_back(SE.getMulExpr(A[3], B[0]));
188 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[2], B[1]));
189 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[1], B[2]));
190 Sum.push_back(SE.getMulExpr(A[0], B[3]));
191 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[3], B[1]));
192 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[2]));
193 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[1], B[3]));
194 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[3], B[2]));
195 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[2], B[3]));
196 Sum.push_back(SE.getMulExpr(A[3], B[3]));
197 EXPECT_EQ(Product->getOperand(3), SE.getAddExpr(Sum));
198 Sum.clear();
199
200 Sum.push_back(SE.getMulExpr(A[4], B[0]));
201 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[3], B[1]));
202 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[2]));
203 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[1], B[3]));
204 Sum.push_back(SE.getMulExpr(A[0], B[4]));
205 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[4], B[1]));
206 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[3], B[2]));
207 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[2], B[3]));
208 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[1], B[4]));
209 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[4], B[2]));
210 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[3], B[3]));
211 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[4]));
212 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[4], B[3]));
213 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[3], B[4]));
214 Sum.push_back(SE.getMulExpr(A[4], B[4]));
215 EXPECT_EQ(Product->getOperand(4), SE.getAddExpr(Sum));
216 Sum.clear();
217
218 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 5), A[4], B[1]));
219 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 10), A[3], B[2]));
220 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 10), A[2], B[3]));
221 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 5), A[1], B[4]));
222 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[4], B[2]));
223 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[3], B[3]));
224 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[2], B[4]));
225 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[4], B[3]));
226 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[3], B[4]));
227 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[4], B[4]));
228 EXPECT_EQ(Product->getOperand(5), SE.getAddExpr(Sum));
229 Sum.clear();
230
231 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 15), A[4], B[2]));
232 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[3], B[3]));
233 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 15), A[2], B[4]));
234 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 60), A[4], B[3]));
235 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 60), A[3], B[4]));
236 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 90), A[4], B[4]));
237 EXPECT_EQ(Product->getOperand(6), SE.getAddExpr(Sum));
238 Sum.clear();
239
240 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 35), A[4], B[3]));
241 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 35), A[3], B[4]));
242 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 140), A[4], B[4]));
243 EXPECT_EQ(Product->getOperand(7), SE.getAddExpr(Sum));
244 Sum.clear();
245#endif
246
247 Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 70), A[4], B[4]));
248 EXPECT_EQ(Product->getOperand(8), SE.getAddExpr(Sum));
Dan Gohman7cac9572010-08-02 23:49:30 +0000249}
250
Tobias Grosser11332e52016-02-21 17:42:10 +0000251TEST_F(ScalarEvolutionsTest, SimplifiedPHI) {
252 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
253 std::vector<Type *>(), false);
254 Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
255 BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
256 BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
257 BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
258 BranchInst::Create(LoopBB, EntryBB);
259 BranchInst::Create(LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)),
260 LoopBB);
261 ReturnInst::Create(Context, nullptr, ExitBB);
262 auto *Ty = Type::getInt32Ty(Context);
263 auto *PN = PHINode::Create(Ty, 2, "", &*LoopBB->begin());
264 PN->addIncoming(Constant::getNullValue(Ty), EntryBB);
265 PN->addIncoming(UndefValue::get(Ty), LoopBB);
266 ScalarEvolution SE = buildSE(*F);
267 auto *S1 = SE.getSCEV(PN);
268 auto *S2 = SE.getSCEV(PN);
Tobias Grosser946ca0a2016-02-22 07:20:40 +0000269 auto *ZeroConst = SE.getConstant(Ty, 0);
Tobias Grosser11332e52016-02-21 17:42:10 +0000270
271 // At some point, only the first call to getSCEV returned the simplified
272 // SCEVConstant and later calls just returned a SCEVUnknown referencing the
273 // PHI node.
Tobias Grosser946ca0a2016-02-22 07:20:40 +0000274 EXPECT_EQ(S1, ZeroConst);
275 EXPECT_EQ(S1, S2);
Tobias Grosser11332e52016-02-21 17:42:10 +0000276}
277
Wei Mi3076cc32016-09-15 04:06:44 +0000278TEST_F(ScalarEvolutionsTest, ExpandPtrTypeSCEV) {
279 // It is to test the fix for PR30213. It exercises the branch in scev
280 // expansion when the value in ValueOffsetPair is a ptr and the offset
281 // is not divisible by the elem type size of value.
282 auto *I8Ty = Type::getInt8Ty(Context);
283 auto *I8PtrTy = Type::getInt8PtrTy(Context);
284 auto *I32Ty = Type::getInt32Ty(Context);
285 auto *I32PtrTy = Type::getInt32PtrTy(Context);
286 FunctionType *FTy =
287 FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
288 Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
289 BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
290 BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
291 BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
292 BranchInst::Create(LoopBB, EntryBB);
293 ReturnInst::Create(Context, nullptr, ExitBB);
294
295 // loop: ; preds = %loop, %entry
296 // %alloca = alloca i32
297 // %gep0 = getelementptr i32, i32* %alloca, i32 1
298 // %bitcast1 = bitcast i32* %gep0 to i8*
299 // %gep1 = getelementptr i8, i8* %bitcast1, i32 1
300 // %gep2 = getelementptr i8, i8* undef, i32 1
301 // %cmp = icmp ult i8* undef, %bitcast1
302 // %select = select i1 %cmp, i8* %gep1, i8* %gep2
303 // %bitcast2 = bitcast i8* %select to i32*
304 // br i1 undef, label %loop, label %exit
305
306 BranchInst *Br = BranchInst::Create(
307 LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)), LoopBB);
308 AllocaInst *Alloca = new AllocaInst(I32Ty, "alloca", Br);
309 ConstantInt *Ci32 = ConstantInt::get(Context, APInt(32, 1));
310 GetElementPtrInst *Gep0 =
311 GetElementPtrInst::Create(I32Ty, Alloca, Ci32, "gep0", Br);
312 CastInst *CastA =
313 CastInst::CreateBitOrPointerCast(Gep0, I8PtrTy, "bitcast1", Br);
314 GetElementPtrInst *Gep1 =
315 GetElementPtrInst::Create(I8Ty, CastA, Ci32, "gep1", Br);
316 GetElementPtrInst *Gep2 = GetElementPtrInst::Create(
317 I8Ty, UndefValue::get(I8PtrTy), Ci32, "gep2", Br);
318 CmpInst *Cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT,
319 UndefValue::get(I8PtrTy), CastA, "cmp", Br);
320 SelectInst *Sel = SelectInst::Create(Cmp, Gep1, Gep2, "select", Br);
321 CastInst *CastB =
322 CastInst::CreateBitOrPointerCast(Sel, I32PtrTy, "bitcast2", Br);
323
324 ScalarEvolution SE = buildSE(*F);
325 auto *S = SE.getSCEV(CastB);
326 SCEVExpander Exp(SE, M.getDataLayout(), "expander");
327 Value *V =
328 Exp.expandCodeFor(cast<SCEVAddExpr>(S)->getOperand(1), nullptr, Br);
329
330 // Expect the expansion code contains:
331 // %0 = bitcast i32* %bitcast2 to i8*
332 // %uglygep = getelementptr i8, i8* %0, i64 -1
333 // %1 = bitcast i8* %uglygep to i32*
334 EXPECT_TRUE(isa<BitCastInst>(V));
335 Instruction *Gep = cast<Instruction>(V)->getPrevNode();
336 EXPECT_TRUE(isa<GetElementPtrInst>(Gep));
337 EXPECT_TRUE(isa<ConstantInt>(Gep->getOperand(1)));
338 EXPECT_EQ(cast<ConstantInt>(Gep->getOperand(1))->getSExtValue(), -1);
339 EXPECT_TRUE(isa<BitCastInst>(Gep->getPrevNode()));
340}
341
Sanjoy Dasb53021d2016-10-30 23:52:50 +0000342static Instruction *getInstructionByName(Function &F, StringRef Name) {
343 for (auto &I : instructions(F))
344 if (I.getName() == Name)
345 return &I;
Sanjoy Das507dd402016-10-18 17:45:16 +0000346 llvm_unreachable("Expected to find instruction!");
347}
348
349TEST_F(ScalarEvolutionsTest, CommutativeExprOperandOrder) {
350 LLVMContext C;
351 SMDiagnostic Err;
352 std::unique_ptr<Module> M = parseAssemblyString(
353 "target datalayout = \"e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128\" "
Sanjoy Dasb53021d2016-10-30 23:52:50 +0000354 " "
Sanjoy Das299e6722016-10-30 23:52:56 +0000355 "@var_0 = external global i32, align 4"
356 "@var_1 = external global i32, align 4"
Sanjoy Dasfd080902016-10-31 03:32:45 +0000357 "@var_2 = external global i32, align 4"
Sanjoy Das299e6722016-10-30 23:52:56 +0000358 " "
Sanjoy Das17078692016-10-31 03:32:43 +0000359 "declare i32 @unknown(i32, i32, i32)"
360 " "
Sanjoy Dasb53021d2016-10-30 23:52:50 +0000361 "define void @f_1(i8* nocapture %arr, i32 %n, i32* %A, i32* %B) "
Sanjoy Das507dd402016-10-18 17:45:16 +0000362 " local_unnamed_addr { "
363 "entry: "
364 " %entrycond = icmp sgt i32 %n, 0 "
365 " br i1 %entrycond, label %loop.ph, label %for.end "
366 " "
367 "loop.ph: "
368 " %a = load i32, i32* %A, align 4 "
369 " %b = load i32, i32* %B, align 4 "
370 " %mul = mul nsw i32 %b, %a "
371 " %iv0.init = getelementptr inbounds i8, i8* %arr, i32 %mul "
372 " br label %loop "
373 " "
374 "loop: "
375 " %iv0 = phi i8* [ %iv0.inc, %loop ], [ %iv0.init, %loop.ph ] "
376 " %iv1 = phi i32 [ %iv1.inc, %loop ], [ 0, %loop.ph ] "
377 " %conv = trunc i32 %iv1 to i8 "
378 " store i8 %conv, i8* %iv0, align 1 "
379 " %iv0.inc = getelementptr inbounds i8, i8* %iv0, i32 %b "
380 " %iv1.inc = add nuw nsw i32 %iv1, 1 "
381 " %exitcond = icmp eq i32 %iv1.inc, %n "
382 " br i1 %exitcond, label %for.end.loopexit, label %loop "
383 " "
384 "for.end.loopexit: "
385 " br label %for.end "
386 " "
387 "for.end: "
388 " ret void "
389 "} "
390 " "
Sanjoy Dasb53021d2016-10-30 23:52:50 +0000391 "define void @f_2(i32* %X, i32* %Y, i32* %Z) { "
Sanjoy Das507dd402016-10-18 17:45:16 +0000392 " %x = load i32, i32* %X "
393 " %y = load i32, i32* %Y "
394 " %z = load i32, i32* %Z "
395 " ret void "
Sanjoy Das299e6722016-10-30 23:52:56 +0000396 "} "
397 " "
Sanjoy Das299e6722016-10-30 23:52:56 +0000398 "define void @f_3() { "
399 " %x = load i32, i32* @var_0"
400 " %y = load i32, i32* @var_1"
Sanjoy Dasfd080902016-10-31 03:32:45 +0000401 " %z = load i32, i32* @var_2"
Sanjoy Das299e6722016-10-30 23:52:56 +0000402 " ret void"
403 "} "
Sanjoy Das17078692016-10-31 03:32:43 +0000404 " "
405 "define void @f_4(i32 %a, i32 %b, i32 %c) { "
406 " %x = call i32 @unknown(i32 %a, i32 %b, i32 %c)"
407 " %y = call i32 @unknown(i32 %b, i32 %c, i32 %a)"
408 " %z = call i32 @unknown(i32 %c, i32 %a, i32 %b)"
409 " ret void"
410 "} "
Sanjoy Das299e6722016-10-30 23:52:56 +0000411 ,
Sanjoy Das507dd402016-10-18 17:45:16 +0000412 Err, C);
413
414 assert(M && "Could not parse module?");
415 assert(!verifyModule(*M) && "Must have been well formed!");
416
Sanjoy Das6764b9a2016-11-10 07:56:05 +0000417 runWithFunctionAndSE(*M, "f_1", [&](Function &F, ScalarEvolution &SE) {
Sanjoy Das3d6e3df2016-10-31 03:32:39 +0000418 auto *IV0 = getInstructionByName(F, "iv0");
419 auto *IV0Inc = getInstructionByName(F, "iv0.inc");
Sanjoy Das507dd402016-10-18 17:45:16 +0000420
Sanjoy Das507dd402016-10-18 17:45:16 +0000421 auto *FirstExprForIV0 = SE.getSCEV(IV0);
422 auto *FirstExprForIV0Inc = SE.getSCEV(IV0Inc);
423 auto *SecondExprForIV0 = SE.getSCEV(IV0);
424
425 EXPECT_TRUE(isa<SCEVAddRecExpr>(FirstExprForIV0));
426 EXPECT_TRUE(isa<SCEVAddRecExpr>(FirstExprForIV0Inc));
427 EXPECT_TRUE(isa<SCEVAddRecExpr>(SecondExprForIV0));
Sanjoy Das3d6e3df2016-10-31 03:32:39 +0000428 });
Sanjoy Das507dd402016-10-18 17:45:16 +0000429
Sanjoy Das17078692016-10-31 03:32:43 +0000430 auto CheckCommutativeMulExprs = [&](ScalarEvolution &SE, const SCEV *A,
431 const SCEV *B, const SCEV *C) {
432 EXPECT_EQ(SE.getMulExpr(A, B), SE.getMulExpr(B, A));
433 EXPECT_EQ(SE.getMulExpr(B, C), SE.getMulExpr(C, B));
434 EXPECT_EQ(SE.getMulExpr(A, C), SE.getMulExpr(C, A));
Sanjoy Das507dd402016-10-18 17:45:16 +0000435
Sanjoy Das17078692016-10-31 03:32:43 +0000436 SmallVector<const SCEV *, 3> Ops0 = {A, B, C};
437 SmallVector<const SCEV *, 3> Ops1 = {A, C, B};
438 SmallVector<const SCEV *, 3> Ops2 = {B, A, C};
439 SmallVector<const SCEV *, 3> Ops3 = {B, C, A};
440 SmallVector<const SCEV *, 3> Ops4 = {C, B, A};
441 SmallVector<const SCEV *, 3> Ops5 = {C, A, B};
Sanjoy Das507dd402016-10-18 17:45:16 +0000442
443 auto *Mul0 = SE.getMulExpr(Ops0);
444 auto *Mul1 = SE.getMulExpr(Ops1);
445 auto *Mul2 = SE.getMulExpr(Ops2);
446 auto *Mul3 = SE.getMulExpr(Ops3);
447 auto *Mul4 = SE.getMulExpr(Ops4);
448 auto *Mul5 = SE.getMulExpr(Ops5);
449
Sanjoy Das17078692016-10-31 03:32:43 +0000450 EXPECT_EQ(Mul0, Mul1) << "Expected " << *Mul0 << " == " << *Mul1;
451 EXPECT_EQ(Mul1, Mul2) << "Expected " << *Mul1 << " == " << *Mul2;
452 EXPECT_EQ(Mul2, Mul3) << "Expected " << *Mul2 << " == " << *Mul3;
453 EXPECT_EQ(Mul3, Mul4) << "Expected " << *Mul3 << " == " << *Mul4;
454 EXPECT_EQ(Mul4, Mul5) << "Expected " << *Mul4 << " == " << *Mul5;
455 };
456
Sanjoy Dasfd080902016-10-31 03:32:45 +0000457 for (StringRef FuncName : {"f_2", "f_3", "f_4"})
Sanjoy Das6764b9a2016-11-10 07:56:05 +0000458 runWithFunctionAndSE(*M, FuncName, [&](Function &F, ScalarEvolution &SE) {
Sanjoy Dasfd080902016-10-31 03:32:45 +0000459 CheckCommutativeMulExprs(SE, SE.getSCEV(getInstructionByName(F, "x")),
460 SE.getSCEV(getInstructionByName(F, "y")),
461 SE.getSCEV(getInstructionByName(F, "z")));
462 });
Sanjoy Das507dd402016-10-18 17:45:16 +0000463}
464
Daniil Fukalov4c3322c2016-11-17 16:07:52 +0000465TEST_F(ScalarEvolutionsTest, SCEVCompareComplexity) {
466 FunctionType *FTy =
467 FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
468 Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
469 BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
470 BasicBlock *LoopBB = BasicBlock::Create(Context, "bb1", F);
471 BranchInst::Create(LoopBB, EntryBB);
472
473 auto *Ty = Type::getInt32Ty(Context);
474 SmallVector<Instruction*, 8> Muls(8), Acc(8), NextAcc(8);
475
476 Acc[0] = PHINode::Create(Ty, 2, "", LoopBB);
477 Acc[1] = PHINode::Create(Ty, 2, "", LoopBB);
478 Acc[2] = PHINode::Create(Ty, 2, "", LoopBB);
479 Acc[3] = PHINode::Create(Ty, 2, "", LoopBB);
480 Acc[4] = PHINode::Create(Ty, 2, "", LoopBB);
481 Acc[5] = PHINode::Create(Ty, 2, "", LoopBB);
482 Acc[6] = PHINode::Create(Ty, 2, "", LoopBB);
483 Acc[7] = PHINode::Create(Ty, 2, "", LoopBB);
484
485 for (int i = 0; i < 20; i++) {
486 Muls[0] = BinaryOperator::CreateMul(Acc[0], Acc[0], "", LoopBB);
487 NextAcc[0] = BinaryOperator::CreateAdd(Muls[0], Acc[4], "", LoopBB);
488 Muls[1] = BinaryOperator::CreateMul(Acc[1], Acc[1], "", LoopBB);
489 NextAcc[1] = BinaryOperator::CreateAdd(Muls[1], Acc[5], "", LoopBB);
490 Muls[2] = BinaryOperator::CreateMul(Acc[2], Acc[2], "", LoopBB);
491 NextAcc[2] = BinaryOperator::CreateAdd(Muls[2], Acc[6], "", LoopBB);
492 Muls[3] = BinaryOperator::CreateMul(Acc[3], Acc[3], "", LoopBB);
493 NextAcc[3] = BinaryOperator::CreateAdd(Muls[3], Acc[7], "", LoopBB);
494
495 Muls[4] = BinaryOperator::CreateMul(Acc[4], Acc[4], "", LoopBB);
496 NextAcc[4] = BinaryOperator::CreateAdd(Muls[4], Acc[0], "", LoopBB);
497 Muls[5] = BinaryOperator::CreateMul(Acc[5], Acc[5], "", LoopBB);
498 NextAcc[5] = BinaryOperator::CreateAdd(Muls[5], Acc[1], "", LoopBB);
499 Muls[6] = BinaryOperator::CreateMul(Acc[6], Acc[6], "", LoopBB);
500 NextAcc[6] = BinaryOperator::CreateAdd(Muls[6], Acc[2], "", LoopBB);
501 Muls[7] = BinaryOperator::CreateMul(Acc[7], Acc[7], "", LoopBB);
502 NextAcc[7] = BinaryOperator::CreateAdd(Muls[7], Acc[3], "", LoopBB);
503 Acc = NextAcc;
504 }
505
506 auto II = LoopBB->begin();
507 for (int i = 0; i < 8; i++) {
508 PHINode *Phi = cast<PHINode>(&*II++);
509 Phi->addIncoming(Acc[i], LoopBB);
510 Phi->addIncoming(UndefValue::get(Ty), EntryBB);
511 }
512
513 BasicBlock *ExitBB = BasicBlock::Create(Context, "bb2", F);
514 BranchInst::Create(LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)),
515 LoopBB);
516
517 Acc[0] = BinaryOperator::CreateAdd(Acc[0], Acc[1], "", ExitBB);
518 Acc[1] = BinaryOperator::CreateAdd(Acc[2], Acc[3], "", ExitBB);
519 Acc[2] = BinaryOperator::CreateAdd(Acc[4], Acc[5], "", ExitBB);
520 Acc[3] = BinaryOperator::CreateAdd(Acc[6], Acc[7], "", ExitBB);
521 Acc[0] = BinaryOperator::CreateAdd(Acc[0], Acc[1], "", ExitBB);
522 Acc[1] = BinaryOperator::CreateAdd(Acc[2], Acc[3], "", ExitBB);
523 Acc[0] = BinaryOperator::CreateAdd(Acc[0], Acc[1], "", ExitBB);
524
525 ReturnInst::Create(Context, nullptr, ExitBB);
526
527 ScalarEvolution SE = buildSE(*F);
528
529 EXPECT_NE(nullptr, SE.getSCEV(Acc[0]));
530}
531
Dan Gohman7cac9572010-08-02 23:49:30 +0000532} // end anonymous namespace
533} // end namespace llvm