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