1ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman//===- ScalarEvolutionsTest.cpp - ScalarEvolution unit tests --------------===//
2ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman//
3ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman//                     The LLVM Compiler Infrastructure
4ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman//
5ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman// This file is distributed under the University of Illinois Open Source
6ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman// License. See LICENSE.TXT for details.
7ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman//
8ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman//===----------------------------------------------------------------------===//
9ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
10dbf545719a22bf03403c1d0137ae0f5726f36de3Craig Topper#include "llvm/Analysis/ScalarEvolutionExpressions.h"
115a88dda4be791426ab4d20a6a6c9c65d66614a27Chandler Carruth#include "llvm/ADT/SmallVector.h"
12dbf545719a22bf03403c1d0137ae0f5726f36de3Craig Topper#include "llvm/Analysis/LoopInfo.h"
130b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
17dbf545719a22bf03403c1d0137ae0f5726f36de3Craig Topper#include "llvm/PassManager.h"
18ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman#include "gtest/gtest.h"
19ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
20ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohmannamespace llvm {
21ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohmannamespace {
22ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
23e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky// We use this fixture to ensure that we clean up ScalarEvolution before
24e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky// deleting the PassManager.
25e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewyckyclass ScalarEvolutionsTest : public testing::Test {
26e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewyckyprotected:
27e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  ScalarEvolutionsTest() : M("", Context), SE(*new ScalarEvolution) {}
28e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  ~ScalarEvolutionsTest() {
29e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky    // Manually clean up, since we allocated new SCEV objects after the
30e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky    // pass was finished.
31e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky    SE.releaseMemory();
32e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  }
33ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  LLVMContext Context;
34e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Module M;
35e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  PassManager PM;
36e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  ScalarEvolution &SE;
37e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky};
38ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
39e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick LewyckyTEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
40db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
415fdd6c8793462549e3593890ec61573da06e3346Jay Foad                                              std::vector<Type *>(), false);
42ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
43ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
44ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  ReturnInst::Create(Context, 0, BB);
45ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
46db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = Type::getInt1Ty(Context);
47ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  Constant *Init = Constant::getNullValue(Ty);
48ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  Value *V0 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V0");
49ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  Value *V1 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V1");
50ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  Value *V2 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V2");
51ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
52ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  // Create a ScalarEvolution and "run" it so that it gets initialized.
53ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  PM.add(&SE);
54ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  PM.run(M);
55ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
56ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEV *S0 = SE.getSCEV(V0);
57ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEV *S1 = SE.getSCEV(V1);
58ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEV *S2 = SE.getSCEV(V2);
59ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
60ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEV *P0 = SE.getAddExpr(S0, S0);
61ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEV *P1 = SE.getAddExpr(S1, S1);
62ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEV *P2 = SE.getAddExpr(S2, S2);
63ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
64ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEVMulExpr *M0 = cast<SCEVMulExpr>(P0);
65ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEVMulExpr *M1 = cast<SCEVMulExpr>(P1);
66ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  const SCEVMulExpr *M2 = cast<SCEVMulExpr>(P2);
67ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
68ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVConstant>(M0->getOperand(0))->getValue()->getZExtValue(),
69ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman            2u);
70ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVConstant>(M1->getOperand(0))->getValue()->getZExtValue(),
71ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman            2u);
72ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVConstant>(M2->getOperand(0))->getValue()->getZExtValue(),
73ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman            2u);
74ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
75ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  // Before the RAUWs, these are all pointing to separate values.
76ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
77ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V1);
78ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V2);
79ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
80ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  // Do some RAUWs.
81ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  V2->replaceAllUsesWith(V1);
82ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  V1->replaceAllUsesWith(V0);
83ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
84ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  // After the RAUWs, these should all be pointing to V0.
85ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
86ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V0);
87ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman  EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V0);
88e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky}
89e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
90e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick LewyckyTEST_F(ScalarEvolutionsTest, SCEVMultiplyAddRecs) {
91e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Type *Ty = Type::getInt32Ty(Context);
92e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  SmallVector<Type *, 10> Types;
93e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Types.append(10, Ty);
94e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
95e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
96e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
97e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  ReturnInst::Create(Context, 0, BB);
98e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
99e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  // Create a ScalarEvolution and "run" it so that it gets initialized.
100e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  PM.add(&SE);
101e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  PM.run(M);
102e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
103e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  // It's possible to produce an empty loop through the default constructor,
104e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  // but you can't add any blocks to it without a LoopInfo pass.
105e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Loop L;
106e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  const_cast<std::vector<BasicBlock*>&>(L.getBlocks()).push_back(BB);
107e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
108e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Function::arg_iterator AI = F->arg_begin();
109e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  SmallVector<const SCEV *, 5> A;
110e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  A.push_back(SE.getSCEV(&*AI++));
111e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  A.push_back(SE.getSCEV(&*AI++));
112e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  A.push_back(SE.getSCEV(&*AI++));
113e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  A.push_back(SE.getSCEV(&*AI++));
114e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  A.push_back(SE.getSCEV(&*AI++));
115e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  const SCEV *A_rec = SE.getAddRecExpr(A, &L, SCEV::FlagAnyWrap);
116e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
117e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  SmallVector<const SCEV *, 5> B;
118e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  B.push_back(SE.getSCEV(&*AI++));
119e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  B.push_back(SE.getSCEV(&*AI++));
120e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  B.push_back(SE.getSCEV(&*AI++));
121e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  B.push_back(SE.getSCEV(&*AI++));
122e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  B.push_back(SE.getSCEV(&*AI++));
123e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  const SCEV *B_rec = SE.getAddRecExpr(B, &L, SCEV::FlagAnyWrap);
124e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
125e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  /* Spot check that we perform this transformation:
126e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky     {A0,+,A1,+,A2,+,A3,+,A4} * {B0,+,B1,+,B2,+,B3,+,B4} =
127e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky     {A0*B0,+,
128e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      A1*B0 + A0*B1 + A1*B1,+,
129e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      A2*B0 + 2A1*B1 + A0*B2 + 2A2*B1 + 2A1*B2 + A2*B2,+,
130e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      A3*B0 + 3A2*B1 + 3A1*B2 + A0*B3 + 3A3*B1 + 6A2*B2 + 3A1*B3 + 3A3*B2 +
131e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky        3A2*B3 + A3*B3,+,
132e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      A4*B0 + 4A3*B1 + 6A2*B2 + 4A1*B3 + A0*B4 + 4A4*B1 + 12A3*B2 + 12A2*B3 +
133e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky        4A1*B4 + 6A4*B2 + 12A3*B3 + 6A2*B4 + 4A4*B3 + 4A3*B4 + A4*B4,+,
134e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      5A4*B1 + 10A3*B2 + 10A2*B3 + 5A1*B4 + 20A4*B2 + 30A3*B3 + 20A2*B4 +
135e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky        30A4*B3 + 30A3*B4 + 20A4*B4,+,
136e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      15A4*B2 + 20A3*B3 + 15A2*B4 + 60A4*B3 + 60A3*B4 + 90A4*B4,+,
137e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      35A4*B3 + 35A3*B4 + 140A4*B4,+,
138e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      70A4*B4}
139e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  */
140e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
141e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  const SCEVAddRecExpr *Product =
142e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky      dyn_cast<SCEVAddRecExpr>(SE.getMulExpr(A_rec, B_rec));
143e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  ASSERT_TRUE(Product);
144e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  ASSERT_EQ(Product->getNumOperands(), 9u);
145e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
146e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  SmallVector<const SCEV *, 16> Sum;
147e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[0], B[0]));
148e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(0), SE.getAddExpr(Sum));
149e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
150e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
151e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  // SCEV produces different an equal but different expression for these.
152e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  // Re-enable when PR11052 is fixed.
153e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky#if 0
154e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[1], B[0]));
155e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[0], B[1]));
156e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[1], B[1]));
157e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(1), SE.getAddExpr(Sum));
158e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
159e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
160e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[2], B[0]));
161e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[1], B[1]));
162e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[0], B[2]));
163e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[2], B[1]));
164e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[1], B[2]));
165e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[2], B[2]));
166e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(2), SE.getAddExpr(Sum));
167e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
168e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
169e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[3], B[0]));
170e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[2], B[1]));
171e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[1], B[2]));
172e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[0], B[3]));
173e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[3], B[1]));
174e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[2]));
175e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[1], B[3]));
176e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[3], B[2]));
177e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[2], B[3]));
178e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[3], B[3]));
179e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(3), SE.getAddExpr(Sum));
180e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
181e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
182e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[4], B[0]));
183e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[3], B[1]));
184e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[2]));
185e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[1], B[3]));
186e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[0], B[4]));
187e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[4], B[1]));
188e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[3], B[2]));
189e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[2], B[3]));
190e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[1], B[4]));
191e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[4], B[2]));
192e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[3], B[3]));
193e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[4]));
194e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[4], B[3]));
195e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[3], B[4]));
196e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(A[4], B[4]));
197e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(4), SE.getAddExpr(Sum));
198e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
199e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
200e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 5), A[4], B[1]));
201e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 10), A[3], B[2]));
202e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 10), A[2], B[3]));
203e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 5), A[1], B[4]));
204e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[4], B[2]));
205e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[3], B[3]));
206e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[2], B[4]));
207e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[4], B[3]));
208e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[3], B[4]));
209e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[4], B[4]));
210e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(5), SE.getAddExpr(Sum));
211e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
212e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
213e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 15), A[4], B[2]));
214e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[3], B[3]));
215e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 15), A[2], B[4]));
216e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 60), A[4], B[3]));
217e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 60), A[3], B[4]));
218e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 90), A[4], B[4]));
219e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(6), SE.getAddExpr(Sum));
220e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
221e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky
222e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 35), A[4], B[3]));
223e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 35), A[3], B[4]));
224e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 140), A[4], B[4]));
225e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(7), SE.getAddExpr(Sum));
226e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.clear();
227e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky#endif
228ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
229e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 70), A[4], B[4]));
230e97728ecf8a0ee69562cc0e7880cfaa65200c624Nick Lewycky  EXPECT_EQ(Product->getOperand(8), SE.getAddExpr(Sum));
231ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman}
232ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman
233ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman}  // end anonymous namespace
234ab37f50838350e1104579fbd1f7c8820473485a5Dan Gohman}  // end namespace llvm
235