1 //===------ IslExprBuilder.cpp ----- Code generate isl AST expressions ----===//
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 //===----------------------------------------------------------------------===//
11 
12 #include "polly/CodeGen/IslExprBuilder.h"
13 #include "polly/CodeGen/RuntimeDebugBuilder.h"
14 #include "polly/Options.h"
15 #include "polly/ScopInfo.h"
16 #include "polly/Support/GICHelper.h"
17 #include "polly/Support/ScopHelper.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
20 
21 using namespace llvm;
22 using namespace polly;
23 
24 /// Different overflow tracking modes.
25 enum OverflowTrackingChoice {
26   OT_NEVER,   ///< Never tack potential overflows.
27   OT_REQUEST, ///< Track potential overflows if requested.
28   OT_ALWAYS   ///< Always track potential overflows.
29 };
30 
31 static cl::opt<OverflowTrackingChoice> OTMode(
32     "polly-overflow-tracking",
33     cl::desc("Define where potential integer overflows in generated "
34              "expressions should be tracked."),
35     cl::values(clEnumValN(OT_NEVER, "never", "Never track the overflow bit."),
36                clEnumValN(OT_REQUEST, "request",
37                           "Track the overflow bit if requested."),
38                clEnumValN(OT_ALWAYS, "always",
39                           "Always track the overflow bit.")),
40     cl::Hidden, cl::init(OT_REQUEST), cl::ZeroOrMore, cl::cat(PollyCategory));
41 
42 IslExprBuilder::IslExprBuilder(Scop &S, PollyIRBuilder &Builder,
43                                IDToValueTy &IDToValue, ValueMapT &GlobalMap,
44                                const DataLayout &DL, ScalarEvolution &SE,
45                                DominatorTree &DT, LoopInfo &LI,
46                                BasicBlock *StartBlock)
47     : S(S), Builder(Builder), IDToValue(IDToValue), GlobalMap(GlobalMap),
48       DL(DL), SE(SE), DT(DT), LI(LI), StartBlock(StartBlock) {
49   OverflowState = (OTMode == OT_ALWAYS) ? Builder.getFalse() : nullptr;
50 }
51 
52 void IslExprBuilder::setTrackOverflow(bool Enable) {
53   // If potential overflows are tracked always or never we ignore requests
54   // to change the behavior.
55   if (OTMode != OT_REQUEST)
56     return;
57 
58   if (Enable) {
59     // If tracking should be enabled initialize the OverflowState.
60     OverflowState = Builder.getFalse();
61   } else {
62     // If tracking should be disabled just unset the OverflowState.
63     OverflowState = nullptr;
64   }
65 }
66 
67 Value *IslExprBuilder::getOverflowState() const {
68   // If the overflow tracking was requested but it is disabled we avoid the
69   // additional nullptr checks at the call sides but instead provide a
70   // meaningful result.
71   if (OTMode == OT_NEVER)
72     return Builder.getFalse();
73   return OverflowState;
74 }
75 
76 Value *IslExprBuilder::createBinOp(BinaryOperator::BinaryOps Opc, Value *LHS,
77                                    Value *RHS, const Twine &Name) {
78   // Handle the plain operation (without overflow tracking) first.
79   if (!OverflowState) {
80     switch (Opc) {
81     case Instruction::Add:
82       return Builder.CreateNSWAdd(LHS, RHS, Name);
83     case Instruction::Sub:
84       return Builder.CreateNSWSub(LHS, RHS, Name);
85     case Instruction::Mul:
86       return Builder.CreateNSWMul(LHS, RHS, Name);
87     default:
88       llvm_unreachable("Unknown binary operator!");
89     }
90   }
91 
92   Function *F = nullptr;
93   Module *M = Builder.GetInsertBlock()->getModule();
94   switch (Opc) {
95   case Instruction::Add:
96     F = Intrinsic::getDeclaration(M, Intrinsic::sadd_with_overflow,
97                                   {LHS->getType()});
98     break;
99   case Instruction::Sub:
100     F = Intrinsic::getDeclaration(M, Intrinsic::ssub_with_overflow,
101                                   {LHS->getType()});
102     break;
103   case Instruction::Mul:
104     F = Intrinsic::getDeclaration(M, Intrinsic::smul_with_overflow,
105                                   {LHS->getType()});
106     break;
107   default:
108     llvm_unreachable("No overflow intrinsic for binary operator found!");
109   }
110 
111   auto *ResultStruct = Builder.CreateCall(F, {LHS, RHS}, Name);
112   assert(ResultStruct->getType()->isStructTy());
113 
114   auto *OverflowFlag =
115       Builder.CreateExtractValue(ResultStruct, 1, Name + ".obit");
116 
117   // If all overflows are tracked we do not combine the results as this could
118   // cause dominance problems. Instead we will always keep the last overflow
119   // flag as current state.
120   if (OTMode == OT_ALWAYS)
121     OverflowState = OverflowFlag;
122   else
123     OverflowState =
124         Builder.CreateOr(OverflowState, OverflowFlag, "polly.overflow.state");
125 
126   return Builder.CreateExtractValue(ResultStruct, 0, Name + ".res");
127 }
128 
129 Value *IslExprBuilder::createAdd(Value *LHS, Value *RHS, const Twine &Name) {
130   return createBinOp(Instruction::Add, LHS, RHS, Name);
131 }
132 
133 Value *IslExprBuilder::createSub(Value *LHS, Value *RHS, const Twine &Name) {
134   return createBinOp(Instruction::Sub, LHS, RHS, Name);
135 }
136 
137 Value *IslExprBuilder::createMul(Value *LHS, Value *RHS, const Twine &Name) {
138   return createBinOp(Instruction::Mul, LHS, RHS, Name);
139 }
140 
141 Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
142   assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
143 
144   if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
145     return T2;
146   else
147     return T1;
148 }
149 
150 Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
151   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
152          "Unsupported unary operation");
153 
154   Value *V;
155   Type *MaxType = getType(Expr);
156   assert(MaxType->isIntegerTy() &&
157          "Unary expressions can only be created for integer types");
158 
159   V = create(isl_ast_expr_get_op_arg(Expr, 0));
160   MaxType = getWidestType(MaxType, V->getType());
161 
162   if (MaxType != V->getType())
163     V = Builder.CreateSExt(V, MaxType);
164 
165   isl_ast_expr_free(Expr);
166   return createSub(ConstantInt::getNullValue(MaxType), V);
167 }
168 
169 Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
170   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
171          "isl ast expression not of type isl_ast_op");
172   assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
173          "We need at least two operands in an n-ary operation");
174 
175   CmpInst::Predicate Pred;
176   switch (isl_ast_expr_get_op_type(Expr)) {
177   default:
178     llvm_unreachable("This is not a an n-ary isl ast expression");
179   case isl_ast_op_max:
180     Pred = CmpInst::ICMP_SGT;
181     break;
182   case isl_ast_op_min:
183     Pred = CmpInst::ICMP_SLT;
184     break;
185   }
186 
187   Value *V = create(isl_ast_expr_get_op_arg(Expr, 0));
188 
189   for (int i = 1; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
190     Value *OpV = create(isl_ast_expr_get_op_arg(Expr, i));
191     Type *Ty = getWidestType(V->getType(), OpV->getType());
192 
193     if (Ty != OpV->getType())
194       OpV = Builder.CreateSExt(OpV, Ty);
195 
196     if (Ty != V->getType())
197       V = Builder.CreateSExt(V, Ty);
198 
199     Value *Cmp = Builder.CreateICmp(Pred, V, OpV);
200     V = Builder.CreateSelect(Cmp, V, OpV);
201   }
202 
203   // TODO: We can truncate the result, if it fits into a smaller type. This can
204   // help in cases where we have larger operands (e.g. i67) but the result is
205   // known to fit into i64. Without the truncation, the larger i67 type may
206   // force all subsequent operations to be performed on a non-native type.
207   isl_ast_expr_free(Expr);
208   return V;
209 }
210 
211 Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) {
212   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
213          "isl ast expression not of type isl_ast_op");
214   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_access &&
215          "not an access isl ast expression");
216   assert(isl_ast_expr_get_op_n_arg(Expr) >= 1 &&
217          "We need at least two operands to create a member access.");
218 
219   Value *Base, *IndexOp, *Access;
220   isl_ast_expr *BaseExpr;
221   isl_id *BaseId;
222 
223   BaseExpr = isl_ast_expr_get_op_arg(Expr, 0);
224   BaseId = isl_ast_expr_get_id(BaseExpr);
225   isl_ast_expr_free(BaseExpr);
226 
227   const ScopArrayInfo *SAI = nullptr;
228 
229   if (PollyDebugPrinting)
230     RuntimeDebugBuilder::createCPUPrinter(Builder, isl_id_get_name(BaseId));
231 
232   if (IDToSAI)
233     SAI = (*IDToSAI)[BaseId];
234 
235   if (!SAI)
236     SAI = ScopArrayInfo::getFromId(BaseId);
237   else
238     isl_id_free(BaseId);
239 
240   assert(SAI && "No ScopArrayInfo found for this isl_id.");
241 
242   Base = SAI->getBasePtr();
243 
244   if (auto NewBase = GlobalMap.lookup(Base))
245     Base = NewBase;
246 
247   assert(Base->getType()->isPointerTy() && "Access base should be a pointer");
248   StringRef BaseName = Base->getName();
249 
250   auto PointerTy = PointerType::get(SAI->getElementType(),
251                                     Base->getType()->getPointerAddressSpace());
252   if (Base->getType() != PointerTy) {
253     Base =
254         Builder.CreateBitCast(Base, PointerTy, "polly.access.cast." + BaseName);
255   }
256 
257   if (isl_ast_expr_get_op_n_arg(Expr) == 1) {
258     isl_ast_expr_free(Expr);
259     if (PollyDebugPrinting)
260       RuntimeDebugBuilder::createCPUPrinter(Builder, "\n");
261     return Base;
262   }
263 
264   IndexOp = nullptr;
265   for (unsigned u = 1, e = isl_ast_expr_get_op_n_arg(Expr); u < e; u++) {
266     Value *NextIndex = create(isl_ast_expr_get_op_arg(Expr, u));
267     assert(NextIndex->getType()->isIntegerTy() &&
268            "Access index should be an integer");
269 
270     if (PollyDebugPrinting)
271       RuntimeDebugBuilder::createCPUPrinter(Builder, "[", NextIndex, "]");
272 
273     if (!IndexOp) {
274       IndexOp = NextIndex;
275     } else {
276       Type *Ty = getWidestType(NextIndex->getType(), IndexOp->getType());
277 
278       if (Ty != NextIndex->getType())
279         NextIndex = Builder.CreateIntCast(NextIndex, Ty, true);
280       if (Ty != IndexOp->getType())
281         IndexOp = Builder.CreateIntCast(IndexOp, Ty, true);
282 
283       IndexOp = createAdd(IndexOp, NextIndex, "polly.access.add." + BaseName);
284     }
285 
286     // For every but the last dimension multiply the size, for the last
287     // dimension we can exit the loop.
288     if (u + 1 >= e)
289       break;
290 
291     const SCEV *DimSCEV = SAI->getDimensionSize(u);
292 
293     llvm::ValueToValueMap Map(GlobalMap.begin(), GlobalMap.end());
294     DimSCEV = SCEVParameterRewriter::rewrite(DimSCEV, SE, Map);
295     Value *DimSize =
296         expandCodeFor(S, SE, DL, "polly", DimSCEV, DimSCEV->getType(),
297                       &*Builder.GetInsertPoint(), nullptr,
298                       StartBlock->getSinglePredecessor());
299 
300     Type *Ty = getWidestType(DimSize->getType(), IndexOp->getType());
301 
302     if (Ty != IndexOp->getType())
303       IndexOp = Builder.CreateSExtOrTrunc(IndexOp, Ty,
304                                           "polly.access.sext." + BaseName);
305     if (Ty != DimSize->getType())
306       DimSize = Builder.CreateSExtOrTrunc(DimSize, Ty,
307                                           "polly.access.sext." + BaseName);
308     IndexOp = createMul(IndexOp, DimSize, "polly.access.mul." + BaseName);
309   }
310 
311   Access = Builder.CreateGEP(Base, IndexOp, "polly.access." + BaseName);
312 
313   if (PollyDebugPrinting)
314     RuntimeDebugBuilder::createCPUPrinter(Builder, "\n");
315   isl_ast_expr_free(Expr);
316   return Access;
317 }
318 
319 Value *IslExprBuilder::createOpAccess(isl_ast_expr *Expr) {
320   Value *Addr = createAccessAddress(Expr);
321   assert(Addr && "Could not create op access address");
322   return Builder.CreateLoad(Addr, Addr->getName() + ".load");
323 }
324 
325 Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
326   Value *LHS, *RHS, *Res;
327   Type *MaxType;
328   isl_ast_op_type OpType;
329 
330   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
331          "isl ast expression not of type isl_ast_op");
332   assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
333          "not a binary isl ast expression");
334 
335   OpType = isl_ast_expr_get_op_type(Expr);
336 
337   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
338   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
339 
340   Type *LHSType = LHS->getType();
341   Type *RHSType = RHS->getType();
342 
343   MaxType = getWidestType(LHSType, RHSType);
344 
345   // Take the result into account when calculating the widest type.
346   //
347   // For operations such as '+' the result may require a type larger than
348   // the type of the individual operands. For other operations such as '/', the
349   // result type cannot be larger than the type of the individual operand. isl
350   // does not calculate correct types for these operations and we consequently
351   // exclude those operations here.
352   switch (OpType) {
353   case isl_ast_op_pdiv_q:
354   case isl_ast_op_pdiv_r:
355   case isl_ast_op_div:
356   case isl_ast_op_fdiv_q:
357   case isl_ast_op_zdiv_r:
358     // Do nothing
359     break;
360   case isl_ast_op_add:
361   case isl_ast_op_sub:
362   case isl_ast_op_mul:
363     MaxType = getWidestType(MaxType, getType(Expr));
364     break;
365   default:
366     llvm_unreachable("This is no binary isl ast expression");
367   }
368 
369   if (MaxType != RHS->getType())
370     RHS = Builder.CreateSExt(RHS, MaxType);
371 
372   if (MaxType != LHS->getType())
373     LHS = Builder.CreateSExt(LHS, MaxType);
374 
375   switch (OpType) {
376   default:
377     llvm_unreachable("This is no binary isl ast expression");
378   case isl_ast_op_add:
379     Res = createAdd(LHS, RHS);
380     break;
381   case isl_ast_op_sub:
382     Res = createSub(LHS, RHS);
383     break;
384   case isl_ast_op_mul:
385     Res = createMul(LHS, RHS);
386     break;
387   case isl_ast_op_div:
388     Res = Builder.CreateSDiv(LHS, RHS, "pexp.div", true);
389     break;
390   case isl_ast_op_pdiv_q: // Dividend is non-negative
391     Res = Builder.CreateUDiv(LHS, RHS, "pexp.p_div_q");
392     break;
393   case isl_ast_op_fdiv_q: { // Round towards -infty
394     if (auto *Const = dyn_cast<ConstantInt>(RHS)) {
395       auto &Val = Const->getValue();
396       if (Val.isPowerOf2() && Val.isNonNegative()) {
397         Res = Builder.CreateAShr(LHS, Val.ceilLogBase2(), "polly.fdiv_q.shr");
398         break;
399       }
400     }
401     // TODO: Review code and check that this calculation does not yield
402     //       incorrect overflow in some edge cases.
403     //
404     // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
405     Value *One = ConstantInt::get(MaxType, 1);
406     Value *Zero = ConstantInt::get(MaxType, 0);
407     Value *Sum1 = createSub(LHS, RHS, "pexp.fdiv_q.0");
408     Value *Sum2 = createAdd(Sum1, One, "pexp.fdiv_q.1");
409     Value *isNegative = Builder.CreateICmpSLT(LHS, Zero, "pexp.fdiv_q.2");
410     Value *Dividend =
411         Builder.CreateSelect(isNegative, Sum2, LHS, "pexp.fdiv_q.3");
412     Res = Builder.CreateSDiv(Dividend, RHS, "pexp.fdiv_q.4");
413     break;
414   }
415   case isl_ast_op_pdiv_r: // Dividend is non-negative
416     Res = Builder.CreateURem(LHS, RHS, "pexp.pdiv_r");
417     break;
418 
419   case isl_ast_op_zdiv_r: // Result only compared against zero
420     Res = Builder.CreateSRem(LHS, RHS, "pexp.zdiv_r");
421     break;
422   }
423 
424   // TODO: We can truncate the result, if it fits into a smaller type. This can
425   // help in cases where we have larger operands (e.g. i67) but the result is
426   // known to fit into i64. Without the truncation, the larger i67 type may
427   // force all subsequent operations to be performed on a non-native type.
428   isl_ast_expr_free(Expr);
429   return Res;
430 }
431 
432 Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
433   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
434          "Unsupported unary isl ast expression");
435   Value *LHS, *RHS, *Cond;
436   Type *MaxType = getType(Expr);
437 
438   Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
439   if (!Cond->getType()->isIntegerTy(1))
440     Cond = Builder.CreateIsNotNull(Cond);
441 
442   LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
443   RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
444 
445   MaxType = getWidestType(MaxType, LHS->getType());
446   MaxType = getWidestType(MaxType, RHS->getType());
447 
448   if (MaxType != RHS->getType())
449     RHS = Builder.CreateSExt(RHS, MaxType);
450 
451   if (MaxType != LHS->getType())
452     LHS = Builder.CreateSExt(LHS, MaxType);
453 
454   // TODO: Do we want to truncate the result?
455   isl_ast_expr_free(Expr);
456   return Builder.CreateSelect(Cond, LHS, RHS);
457 }
458 
459 Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
460   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
461          "Expected an isl_ast_expr_op expression");
462 
463   Value *LHS, *RHS, *Res;
464 
465   auto *Op0 = isl_ast_expr_get_op_arg(Expr, 0);
466   auto *Op1 = isl_ast_expr_get_op_arg(Expr, 1);
467   bool HasNonAddressOfOperand =
468       isl_ast_expr_get_type(Op0) != isl_ast_expr_op ||
469       isl_ast_expr_get_type(Op1) != isl_ast_expr_op ||
470       isl_ast_expr_get_op_type(Op0) != isl_ast_op_address_of ||
471       isl_ast_expr_get_op_type(Op1) != isl_ast_op_address_of;
472 
473   LHS = create(Op0);
474   RHS = create(Op1);
475 
476   auto *LHSTy = LHS->getType();
477   auto *RHSTy = RHS->getType();
478   bool IsPtrType = LHSTy->isPointerTy() || RHSTy->isPointerTy();
479   bool UseUnsignedCmp = IsPtrType && !HasNonAddressOfOperand;
480 
481   auto *PtrAsIntTy = Builder.getIntNTy(DL.getPointerSizeInBits());
482   if (LHSTy->isPointerTy())
483     LHS = Builder.CreatePtrToInt(LHS, PtrAsIntTy);
484   if (RHSTy->isPointerTy())
485     RHS = Builder.CreatePtrToInt(RHS, PtrAsIntTy);
486 
487   if (LHS->getType() != RHS->getType()) {
488     Type *MaxType = LHS->getType();
489     MaxType = getWidestType(MaxType, RHS->getType());
490 
491     if (MaxType != RHS->getType())
492       RHS = Builder.CreateSExt(RHS, MaxType);
493 
494     if (MaxType != LHS->getType())
495       LHS = Builder.CreateSExt(LHS, MaxType);
496   }
497 
498   isl_ast_op_type OpType = isl_ast_expr_get_op_type(Expr);
499   assert(OpType >= isl_ast_op_eq && OpType <= isl_ast_op_gt &&
500          "Unsupported ICmp isl ast expression");
501   assert(isl_ast_op_eq + 4 == isl_ast_op_gt &&
502          "Isl ast op type interface changed");
503 
504   CmpInst::Predicate Predicates[5][2] = {
505       {CmpInst::ICMP_EQ, CmpInst::ICMP_EQ},
506       {CmpInst::ICMP_SLE, CmpInst::ICMP_ULE},
507       {CmpInst::ICMP_SLT, CmpInst::ICMP_ULT},
508       {CmpInst::ICMP_SGE, CmpInst::ICMP_UGE},
509       {CmpInst::ICMP_SGT, CmpInst::ICMP_UGT},
510   };
511 
512   Res = Builder.CreateICmp(Predicates[OpType - isl_ast_op_eq][UseUnsignedCmp],
513                            LHS, RHS);
514 
515   isl_ast_expr_free(Expr);
516   return Res;
517 }
518 
519 Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
520   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
521          "Expected an isl_ast_expr_op expression");
522 
523   Value *LHS, *RHS, *Res;
524   isl_ast_op_type OpType;
525 
526   OpType = isl_ast_expr_get_op_type(Expr);
527 
528   assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
529          "Unsupported isl_ast_op_type");
530 
531   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
532   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
533 
534   // Even though the isl pretty printer prints the expressions as 'exp && exp'
535   // or 'exp || exp', we actually code generate the bitwise expressions
536   // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
537   // but it is, due to the use of i1 types, otherwise equivalent. The reason
538   // to go for bitwise operations is, that we assume the reduced control flow
539   // will outweigh the overhead introduced by evaluating unneeded expressions.
540   // The isl code generation currently does not take advantage of the fact that
541   // the expression after an '||' or '&&' is in some cases not evaluated.
542   // Evaluating it anyways does not cause any undefined behaviour.
543   //
544   // TODO: Document in isl itself, that the unconditionally evaluating the
545   // second part of '||' or '&&' expressions is safe.
546   if (!LHS->getType()->isIntegerTy(1))
547     LHS = Builder.CreateIsNotNull(LHS);
548   if (!RHS->getType()->isIntegerTy(1))
549     RHS = Builder.CreateIsNotNull(RHS);
550 
551   switch (OpType) {
552   default:
553     llvm_unreachable("Unsupported boolean expression");
554   case isl_ast_op_and:
555     Res = Builder.CreateAnd(LHS, RHS);
556     break;
557   case isl_ast_op_or:
558     Res = Builder.CreateOr(LHS, RHS);
559     break;
560   }
561 
562   isl_ast_expr_free(Expr);
563   return Res;
564 }
565 
566 Value *
567 IslExprBuilder::createOpBooleanConditional(__isl_take isl_ast_expr *Expr) {
568   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
569          "Expected an isl_ast_expr_op expression");
570 
571   Value *LHS, *RHS;
572   isl_ast_op_type OpType;
573 
574   Function *F = Builder.GetInsertBlock()->getParent();
575   LLVMContext &Context = F->getContext();
576 
577   OpType = isl_ast_expr_get_op_type(Expr);
578 
579   assert((OpType == isl_ast_op_and_then || OpType == isl_ast_op_or_else) &&
580          "Unsupported isl_ast_op_type");
581 
582   auto InsertBB = Builder.GetInsertBlock();
583   auto InsertPoint = Builder.GetInsertPoint();
584   auto NextBB = SplitBlock(InsertBB, &*InsertPoint, &DT, &LI);
585   BasicBlock *CondBB = BasicBlock::Create(Context, "polly.cond", F);
586   LI.changeLoopFor(CondBB, LI.getLoopFor(InsertBB));
587   DT.addNewBlock(CondBB, InsertBB);
588 
589   InsertBB->getTerminator()->eraseFromParent();
590   Builder.SetInsertPoint(InsertBB);
591   auto BR = Builder.CreateCondBr(Builder.getTrue(), NextBB, CondBB);
592 
593   Builder.SetInsertPoint(CondBB);
594   Builder.CreateBr(NextBB);
595 
596   Builder.SetInsertPoint(InsertBB->getTerminator());
597 
598   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
599   if (!LHS->getType()->isIntegerTy(1))
600     LHS = Builder.CreateIsNotNull(LHS);
601   auto LeftBB = Builder.GetInsertBlock();
602 
603   if (OpType == isl_ast_op_and || OpType == isl_ast_op_and_then)
604     BR->setCondition(Builder.CreateNeg(LHS));
605   else
606     BR->setCondition(LHS);
607 
608   Builder.SetInsertPoint(CondBB->getTerminator());
609   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
610   if (!RHS->getType()->isIntegerTy(1))
611     RHS = Builder.CreateIsNotNull(RHS);
612   auto RightBB = Builder.GetInsertBlock();
613 
614   Builder.SetInsertPoint(NextBB->getTerminator());
615   auto PHI = Builder.CreatePHI(Builder.getInt1Ty(), 2);
616   PHI->addIncoming(OpType == isl_ast_op_and_then ? Builder.getFalse()
617                                                  : Builder.getTrue(),
618                    LeftBB);
619   PHI->addIncoming(RHS, RightBB);
620 
621   isl_ast_expr_free(Expr);
622   return PHI;
623 }
624 
625 Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
626   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
627          "Expression not of type isl_ast_expr_op");
628   switch (isl_ast_expr_get_op_type(Expr)) {
629   case isl_ast_op_error:
630   case isl_ast_op_cond:
631   case isl_ast_op_call:
632   case isl_ast_op_member:
633     llvm_unreachable("Unsupported isl ast expression");
634   case isl_ast_op_access:
635     return createOpAccess(Expr);
636   case isl_ast_op_max:
637   case isl_ast_op_min:
638     return createOpNAry(Expr);
639   case isl_ast_op_add:
640   case isl_ast_op_sub:
641   case isl_ast_op_mul:
642   case isl_ast_op_div:
643   case isl_ast_op_fdiv_q: // Round towards -infty
644   case isl_ast_op_pdiv_q: // Dividend is non-negative
645   case isl_ast_op_pdiv_r: // Dividend is non-negative
646   case isl_ast_op_zdiv_r: // Result only compared against zero
647     return createOpBin(Expr);
648   case isl_ast_op_minus:
649     return createOpUnary(Expr);
650   case isl_ast_op_select:
651     return createOpSelect(Expr);
652   case isl_ast_op_and:
653   case isl_ast_op_or:
654     return createOpBoolean(Expr);
655   case isl_ast_op_and_then:
656   case isl_ast_op_or_else:
657     return createOpBooleanConditional(Expr);
658   case isl_ast_op_eq:
659   case isl_ast_op_le:
660   case isl_ast_op_lt:
661   case isl_ast_op_ge:
662   case isl_ast_op_gt:
663     return createOpICmp(Expr);
664   case isl_ast_op_address_of:
665     return createOpAddressOf(Expr);
666   }
667 
668   llvm_unreachable("Unsupported isl_ast_expr_op kind.");
669 }
670 
671 Value *IslExprBuilder::createOpAddressOf(__isl_take isl_ast_expr *Expr) {
672   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
673          "Expected an isl_ast_expr_op expression.");
674   assert(isl_ast_expr_get_op_n_arg(Expr) == 1 && "Address of should be unary.");
675 
676   isl_ast_expr *Op = isl_ast_expr_get_op_arg(Expr, 0);
677   assert(isl_ast_expr_get_type(Op) == isl_ast_expr_op &&
678          "Expected address of operator to be an isl_ast_expr_op expression.");
679   assert(isl_ast_expr_get_op_type(Op) == isl_ast_op_access &&
680          "Expected address of operator to be an access expression.");
681 
682   Value *V = createAccessAddress(Op);
683 
684   isl_ast_expr_free(Expr);
685 
686   return V;
687 }
688 
689 Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
690   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
691          "Expression not of type isl_ast_expr_ident");
692 
693   isl_id *Id;
694   Value *V;
695 
696   Id = isl_ast_expr_get_id(Expr);
697 
698   assert(IDToValue.count(Id) && "Identifier not found");
699 
700   V = IDToValue[Id];
701   if (!V)
702     V = UndefValue::get(getType(Expr));
703 
704   if (V->getType()->isPointerTy())
705     V = Builder.CreatePtrToInt(V, Builder.getIntNTy(DL.getPointerSizeInBits()));
706 
707   assert(V && "Unknown parameter id found");
708 
709   isl_id_free(Id);
710   isl_ast_expr_free(Expr);
711 
712   return V;
713 }
714 
715 IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
716   // XXX: We assume i64 is large enough. This is often true, but in general
717   //      incorrect. Also, on 32bit architectures, it would be beneficial to
718   //      use a smaller type. We can and should directly derive this information
719   //      during code generation.
720   return IntegerType::get(Builder.getContext(), 64);
721 }
722 
723 Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
724   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
725          "Expression not of type isl_ast_expr_int");
726   isl_val *Val;
727   Value *V;
728   APInt APValue;
729   IntegerType *T;
730 
731   Val = isl_ast_expr_get_val(Expr);
732   APValue = APIntFromVal(Val);
733 
734   auto BitWidth = APValue.getBitWidth();
735   if (BitWidth <= 64)
736     T = getType(Expr);
737   else
738     T = Builder.getIntNTy(BitWidth);
739 
740   APValue = APValue.sextOrSelf(T->getBitWidth());
741   V = ConstantInt::get(T, APValue);
742 
743   isl_ast_expr_free(Expr);
744   return V;
745 }
746 
747 Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
748   switch (isl_ast_expr_get_type(Expr)) {
749   case isl_ast_expr_error:
750     llvm_unreachable("Code generation error");
751   case isl_ast_expr_op:
752     return createOp(Expr);
753   case isl_ast_expr_id:
754     return createId(Expr);
755   case isl_ast_expr_int:
756     return createInt(Expr);
757   }
758 
759   llvm_unreachable("Unexpected enum value");
760 }
761