This reverts recent expression type changes

The recent expression type changes still need more discussion, which will happen
on phabricator or on the mailing list. The precise list of commits reverted are:

- "Refactor division generation code"
- "[NFC] Generate runtime checks after the SCoP"
- "[FIX] Determine insertion point during SCEV expansion"
- "Look through IntToPtr & PtrToInt instructions"
- "Use minimal types for generated expressions"
- "Temporarily promote values to i64 again"
- "[NFC] Avoid unnecessary comparison for min/max expressions"
- "[Polly] Fix -Wunused-variable warnings (NFC)"
- "[NFC] Simplify min/max expression generation"
- "Simplify the type adjustment in the IslExprBuilder"

Some of them are just reverted as we would otherwise get conflicts. I will try
to re-commit them if possible.

llvm-svn: 272483
diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp
index b434144..ce1098f 100644
--- a/polly/lib/CodeGen/CodeGeneration.cpp
+++ b/polly/lib/CodeGen/CodeGeneration.cpp
@@ -191,12 +191,7 @@
     } else {
 
       NodeBuilder.addParameters(S.getContext());
-      SplitBlock = Builder.GetInsertBlock();
 
-      Builder.SetInsertPoint(&StartBlock->front());
-      NodeBuilder.create(AstRoot);
-
-      Builder.SetInsertPoint(SplitBlock->getTerminator());
       ExprBuilder.setTrackOverflow(true);
       Value *RTC = buildRTC(Builder, ExprBuilder);
       Value *OverflowHappened = Builder.CreateNot(
@@ -204,7 +199,10 @@
       RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
       ExprBuilder.setTrackOverflow(false);
 
-      SplitBlock->getTerminator()->setOperand(0, RTC);
+      Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC);
+      Builder.SetInsertPoint(&StartBlock->front());
+
+      NodeBuilder.create(AstRoot);
 
       NodeBuilder.finalizeSCoP(S);
       fixRegionInfo(EnteringBB->getParent(), R->getParent());
diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp
index f524954..5bcd784 100644
--- a/polly/lib/CodeGen/IslAst.cpp
+++ b/polly/lib/CodeGen/IslAst.cpp
@@ -331,7 +331,8 @@
   return NonAliasGroup;
 }
 
-__isl_give isl_ast_expr *IslAst::buildRunCondition() {
+__isl_give isl_ast_expr *
+IslAst::buildRunCondition(Scop *S, __isl_keep isl_ast_build *Build) {
   isl_ast_expr *RunCondition;
 
   // The conditions that need to be checked at run-time for this scop are
@@ -392,7 +393,8 @@
 }
 
 IslAst::IslAst(Scop *Scop)
-    : S(Scop), Root(nullptr), Build(nullptr), Ctx(Scop->getSharedIslCtx()) {}
+    : S(Scop), Root(nullptr), RunCondition(nullptr),
+      Ctx(Scop->getSharedIslCtx()) {}
 
 void IslAst::init(const Dependences &D) {
   bool PerformParallelTest = PollyParallel || DetectParallel ||
@@ -405,6 +407,7 @@
   isl_ctx *Ctx = S->getIslCtx();
   isl_options_set_ast_build_atomic_upper_bound(Ctx, true);
   isl_options_set_ast_build_detect_min_max(Ctx, true);
+  isl_ast_build *Build;
   AstBuildUserInfo BuildInfo;
 
   if (UseContext)
@@ -430,7 +433,11 @@
                                               &BuildInfo);
   }
 
+  RunCondition = buildRunCondition(S, Build);
+
   Root = isl_ast_build_node_from_schedule(Build, S->getScheduleTree());
+
+  isl_ast_build_free(Build);
 }
 
 IslAst *IslAst::create(Scop *Scop, const Dependences &D) {
@@ -441,10 +448,13 @@
 
 IslAst::~IslAst() {
   isl_ast_node_free(Root);
-  isl_ast_build_free(Build);
+  isl_ast_expr_free(RunCondition);
 }
 
 __isl_give isl_ast_node *IslAst::getAst() { return isl_ast_node_copy(Root); }
+__isl_give isl_ast_expr *IslAst::getRunCondition() {
+  return isl_ast_expr_copy(RunCondition);
+}
 
 void IslAstInfo::releaseMemory() {
   if (Ast) {
@@ -470,7 +480,7 @@
 
 __isl_give isl_ast_node *IslAstInfo::getAst() const { return Ast->getAst(); }
 __isl_give isl_ast_expr *IslAstInfo::getRunCondition() const {
-  return Ast->buildRunCondition();
+  return Ast->getRunCondition();
 }
 
 IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) {
diff --git a/polly/lib/CodeGen/IslExprBuilder.cpp b/polly/lib/CodeGen/IslExprBuilder.cpp
index 069e23d..62c166f 100644
--- a/polly/lib/CodeGen/IslExprBuilder.cpp
+++ b/polly/lib/CodeGen/IslExprBuilder.cpp
@@ -39,12 +39,6 @@
                clEnumValEnd),
     cl::Hidden, cl::init(OT_REQUEST), cl::ZeroOrMore, cl::cat(PollyCategory));
 
-// @TODO This should actually be derived from the DataLayout.
-static cl::opt<unsigned> PollyMaxAllowedBitWidth(
-    "polly-max-expr-bit-width",
-    cl::desc("The maximal bit with for generated expressions."), cl::Hidden,
-    cl::ZeroOrMore, cl::init(64), cl::cat(PollyCategory));
-
 IslExprBuilder::IslExprBuilder(Scop &S, PollyIRBuilder &Builder,
                                IDToValueTy &IDToValue, ValueMapT &GlobalMap,
                                const DataLayout &DL, ScalarEvolution &SE,
@@ -80,23 +74,8 @@
 
 Value *IslExprBuilder::createBinOp(BinaryOperator::BinaryOps Opc, Value *LHS,
                                    Value *RHS, const Twine &Name) {
-  // Flag that is true if the computation cannot overflow.
-  bool IsSafeToCompute = false;
-  switch (Opc) {
-  case Instruction::Add:
-  case Instruction::Sub:
-    IsSafeToCompute = adjustTypesForSafeAddition(LHS, RHS);
-    break;
-  case Instruction::Mul:
-    IsSafeToCompute = adjustTypesForSafeMultiplication(LHS, RHS);
-    break;
-  default:
-    llvm_unreachable("Unknown binary operator!");
-  }
-
-  // Handle the plain operation (without overflow tracking or a safe
-  // computation) first.
-  if (!OverflowState || (IsSafeToCompute && (OTMode != OT_ALWAYS))) {
+  // Handle the plain operation (without overflow tracking) first.
+  if (!OverflowState) {
     switch (Opc) {
     case Instruction::Add:
       return Builder.CreateNSWAdd(LHS, RHS, Name);
@@ -158,7 +137,7 @@
   return createBinOp(Instruction::Mul, LHS, RHS, Name);
 }
 
-static Type *getWidestType(Type *T1, Type *T2) {
+Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
   assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
 
   if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
@@ -167,63 +146,23 @@
     return T1;
 }
 
-void IslExprBuilder::unifyTypes(Value *&V0, Value *&V1, Value *&V2) {
-  auto *T0 = V0->getType();
-  auto *T1 = V1->getType();
-  auto *T2 = V2->getType();
-  if (T0 == T1 && T1 == T2)
-    return;
-  auto *MaxT = getWidestType(T0, T1);
-  MaxT = getWidestType(MaxT, T2);
-  V0 = Builder.CreateSExt(V0, MaxT);
-  V1 = Builder.CreateSExt(V1, MaxT);
-  V2 = Builder.CreateSExt(V2, MaxT);
-}
-
-bool IslExprBuilder::adjustTypesForSafeComputation(Value *&LHS, Value *&RHS,
-                                                   unsigned RequiredBitWidth) {
-  unsigned LBitWidth = LHS->getType()->getPrimitiveSizeInBits();
-  unsigned RBitWidth = RHS->getType()->getPrimitiveSizeInBits();
-  unsigned MaxUsedBitWidth = std::max(LBitWidth, RBitWidth);
-
-  // @TODO For now use the maximal bit width if the required one is to large but
-  //       note that this is not sound.
-  unsigned MaxAllowedBitWidth = PollyMaxAllowedBitWidth;
-  unsigned NewBitWidth =
-      std::max(MaxUsedBitWidth, std::min(MaxAllowedBitWidth, RequiredBitWidth));
-
-  Type *Ty = Builder.getIntNTy(NewBitWidth);
-  LHS = Builder.CreateSExt(LHS, Ty);
-  RHS = Builder.CreateSExt(RHS, Ty);
-
-  // If the new bit width is not large enough the computation is not sound.
-  return NewBitWidth == RequiredBitWidth;
-}
-
-bool IslExprBuilder::adjustTypesForSafeAddition(Value *&LHS, Value *&RHS) {
-  unsigned LBitWidth = LHS->getType()->getPrimitiveSizeInBits();
-  unsigned RBitWidth = RHS->getType()->getPrimitiveSizeInBits();
-  return adjustTypesForSafeComputation(LHS, RHS,
-                                       std::max(LBitWidth, RBitWidth) + 1);
-}
-
-bool IslExprBuilder::adjustTypesForSafeMultiplication(Value *&LHS,
-                                                      Value *&RHS) {
-  unsigned LBitWidth = LHS->getType()->getPrimitiveSizeInBits();
-  unsigned RBitWidth = RHS->getType()->getPrimitiveSizeInBits();
-  return adjustTypesForSafeComputation(LHS, RHS, LBitWidth + RBitWidth);
-}
-
 Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
          "Unsupported unary operation");
 
-  auto *V = create(isl_ast_expr_get_op_arg(Expr, 0));
-  assert(V->getType()->isIntegerTy() &&
+  Value *V;
+  Type *MaxType = getType(Expr);
+  assert(MaxType->isIntegerTy() &&
          "Unary expressions can only be created for integer types");
 
+  V = create(isl_ast_expr_get_op_arg(Expr, 0));
+  MaxType = getWidestType(MaxType, V->getType());
+
+  if (MaxType != V->getType())
+    V = Builder.CreateSExt(V, MaxType);
+
   isl_ast_expr_free(Expr);
-  return createSub(ConstantInt::getNullValue(V->getType()), V);
+  return createSub(ConstantInt::getNullValue(MaxType), V);
 }
 
 Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
@@ -231,20 +170,44 @@
          "isl ast expression not of type isl_ast_op");
   assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
          "We need at least two operands in an n-ary operation");
-  assert((isl_ast_expr_get_op_type(Expr) == isl_ast_op_max ||
-          isl_ast_expr_get_op_type(Expr) == isl_ast_op_min) &&
-         "This is no n-ary isl ast expression");
 
-  bool IsMax = isl_ast_expr_get_op_type(Expr) == isl_ast_op_max;
-  auto Pred = IsMax ? CmpInst::ICMP_SGT : CmpInst::ICMP_SLT;
-  auto *V = create(isl_ast_expr_get_op_arg(Expr, 0));
+  Value *V;
 
-  for (int i = 1; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
-    auto *OpV = create(isl_ast_expr_get_op_arg(Expr, i));
-    unifyTypes(V, OpV);
-    V = Builder.CreateSelect(Builder.CreateICmp(Pred, V, OpV), V, OpV);
+  V = create(isl_ast_expr_get_op_arg(Expr, 0));
+
+  for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
+    Value *OpV;
+    OpV = create(isl_ast_expr_get_op_arg(Expr, i));
+
+    Type *Ty = getWidestType(V->getType(), OpV->getType());
+
+    if (Ty != OpV->getType())
+      OpV = Builder.CreateSExt(OpV, Ty);
+
+    if (Ty != V->getType())
+      V = Builder.CreateSExt(V, Ty);
+
+    switch (isl_ast_expr_get_op_type(Expr)) {
+    default:
+      llvm_unreachable("This is no n-ary isl ast expression");
+
+    case isl_ast_op_max: {
+      Value *Cmp = Builder.CreateICmpSGT(V, OpV);
+      V = Builder.CreateSelect(Cmp, V, OpV);
+      continue;
+    }
+    case isl_ast_op_min: {
+      Value *Cmp = Builder.CreateICmpSLT(V, OpV);
+      V = Builder.CreateSelect(Cmp, V, OpV);
+      continue;
+    }
+    }
   }
 
+  // TODO: We can truncate the result, if it fits into a smaller type. This can
+  // help in cases where we have larger operands (e.g. i67) but the result is
+  // known to fit into i64. Without the truncation, the larger i67 type may
+  // force all subsequent operations to be performed on a non-native type.
   isl_ast_expr_free(Expr);
   return V;
 }
@@ -287,8 +250,18 @@
     assert(NextIndex->getType()->isIntegerTy() &&
            "Access index should be an integer");
 
-    IndexOp = !IndexOp ? NextIndex : createAdd(IndexOp, NextIndex,
-                                               "polly.access.add." + BaseName);
+    if (!IndexOp) {
+      IndexOp = NextIndex;
+    } else {
+      Type *Ty = getWidestType(NextIndex->getType(), IndexOp->getType());
+
+      if (Ty != NextIndex->getType())
+        NextIndex = Builder.CreateIntCast(NextIndex, Ty, true);
+      if (Ty != IndexOp->getType())
+        IndexOp = Builder.CreateIntCast(IndexOp, Ty, true);
+
+      IndexOp = createAdd(IndexOp, NextIndex, "polly.access.add." + BaseName);
+    }
 
     // For every but the last dimension multiply the size, for the last
     // dimension we can exit the loop.
@@ -303,6 +276,14 @@
         expandCodeFor(S, SE, DL, "polly", DimSCEV, DimSCEV->getType(),
                       &*Builder.GetInsertPoint());
 
+    Type *Ty = getWidestType(DimSize->getType(), IndexOp->getType());
+
+    if (Ty != IndexOp->getType())
+      IndexOp = Builder.CreateSExtOrTrunc(IndexOp, Ty,
+                                          "polly.access.sext." + BaseName);
+    if (Ty != DimSize->getType())
+      DimSize = Builder.CreateSExtOrTrunc(DimSize, Ty,
+                                          "polly.access.sext." + BaseName);
     IndexOp = createMul(IndexOp, DimSize, "polly.access.mul." + BaseName);
   }
 
@@ -318,50 +299,9 @@
   return Builder.CreateLoad(Addr, Addr->getName() + ".load");
 }
 
-Value *IslExprBuilder::createDiv(Value *LHS, Value *RHS, DivisionMode DM) {
-  auto *ConstRHS = dyn_cast<ConstantInt>(RHS);
-  unsigned UnusedBits = 0;
-  Value *Res = nullptr;
-
-  if (ConstRHS)
-    UnusedBits = ConstRHS->getValue().logBase2();
-
-  if (ConstRHS && ConstRHS->getValue().isPowerOf2() &&
-      ConstRHS->getValue().isNonNegative())
-    Res = Builder.CreateAShr(LHS, UnusedBits, "polly.div.shr");
-  else if (DM == DM_SIGNED)
-    Res = Builder.CreateSDiv(LHS, RHS, "pexp.div", true);
-  else if (DM == DM_UNSIGNED)
-    Res = Builder.CreateUDiv(LHS, RHS, "pexp.p_div_q");
-  else {
-    assert(DM == DM_FLOORED);
-    // TODO: Review code and check that this calculation does not yield
-    //       incorrect overflow in some bordercases.
-    //
-    // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
-    Value *Sum1 = createSub(LHS, RHS, "pexp.fdiv_q.0");
-    Value *One = ConstantInt::get(Sum1->getType(), 1);
-    Value *Sum2 = createAdd(Sum1, One, "pexp.fdiv_q.1");
-    Value *Zero = ConstantInt::get(LHS->getType(), 0);
-    Value *isNegative = Builder.CreateICmpSLT(LHS, Zero, "pexp.fdiv_q.2");
-    unifyTypes(LHS, Sum2);
-    Value *Dividend =
-        Builder.CreateSelect(isNegative, Sum2, LHS, "pexp.fdiv_q.3");
-    unifyTypes(Dividend, RHS);
-    Res = Builder.CreateSDiv(Dividend, RHS, "pexp.fdiv_q.4");
-  }
-
-  if (UnusedBits) {
-    auto RequiredBits = Res->getType()->getPrimitiveSizeInBits() - UnusedBits;
-    Res = Builder.CreateTrunc(Res, Builder.getIntNTy(RequiredBits),
-                              "polly.div.trunc");
-  }
-
-  return Res;
-}
-
 Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
   Value *LHS, *RHS, *Res;
+  Type *MaxType;
   isl_ast_op_type OpType;
 
   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
@@ -374,25 +314,41 @@
   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
 
-  // For possibly overflowing operations we will later adjust types but
-  // for others we do it now as we will directly create the operations.
+  Type *LHSType = LHS->getType();
+  Type *RHSType = RHS->getType();
+
+  MaxType = getWidestType(LHSType, RHSType);
+
+  // Take the result into account when calculating the widest type.
+  //
+  // For operations such as '+' the result may require a type larger than
+  // the type of the individual operands. For other operations such as '/', the
+  // result type cannot be larger than the type of the individual operand. isl
+  // does not calculate correct types for these operations and we consequently
+  // exclude those operations here.
   switch (OpType) {
   case isl_ast_op_pdiv_q:
   case isl_ast_op_pdiv_r:
   case isl_ast_op_div:
   case isl_ast_op_fdiv_q:
   case isl_ast_op_zdiv_r:
-    unifyTypes(LHS, RHS);
+    // Do nothing
     break;
   case isl_ast_op_add:
   case isl_ast_op_sub:
   case isl_ast_op_mul:
-    // Do nothing
+    MaxType = getWidestType(MaxType, getType(Expr));
     break;
   default:
     llvm_unreachable("This is no binary isl ast expression");
   }
 
+  if (MaxType != RHS->getType())
+    RHS = Builder.CreateSExt(RHS, MaxType);
+
+  if (MaxType != LHS->getType())
+    LHS = Builder.CreateSExt(LHS, MaxType);
+
   switch (OpType) {
   default:
     llvm_unreachable("This is no binary isl ast expression");
@@ -406,22 +362,46 @@
     Res = createMul(LHS, RHS);
     break;
   case isl_ast_op_div:
-    Res = createDiv(LHS, RHS, DM_SIGNED);
+    Res = Builder.CreateSDiv(LHS, RHS, "pexp.div", true);
     break;
   case isl_ast_op_pdiv_q: // Dividend is non-negative
-    Res = createDiv(LHS, RHS, DM_UNSIGNED);
+    Res = Builder.CreateUDiv(LHS, RHS, "pexp.p_div_q");
     break;
-  case isl_ast_op_fdiv_q: // Round towards -infty
-    Res = createDiv(LHS, RHS, DM_FLOORED);
+  case isl_ast_op_fdiv_q: { // Round towards -infty
+    if (auto *Const = dyn_cast<ConstantInt>(RHS)) {
+      auto &Val = Const->getValue();
+      if (Val.isPowerOf2() && Val.isNonNegative()) {
+        Res = Builder.CreateAShr(LHS, Val.ceilLogBase2(), "polly.fdiv_q.shr");
+        break;
+      }
+    }
+    // TODO: Review code and check that this calculation does not yield
+    //       incorrect overflow in some bordercases.
+    //
+    // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
+    Value *One = ConstantInt::get(MaxType, 1);
+    Value *Zero = ConstantInt::get(MaxType, 0);
+    Value *Sum1 = createSub(LHS, RHS, "pexp.fdiv_q.0");
+    Value *Sum2 = createAdd(Sum1, One, "pexp.fdiv_q.1");
+    Value *isNegative = Builder.CreateICmpSLT(LHS, Zero, "pexp.fdiv_q.2");
+    Value *Dividend =
+        Builder.CreateSelect(isNegative, Sum2, LHS, "pexp.fdiv_q.3");
+    Res = Builder.CreateSDiv(Dividend, RHS, "pexp.fdiv_q.4");
     break;
+  }
   case isl_ast_op_pdiv_r: // Dividend is non-negative
     Res = Builder.CreateURem(LHS, RHS, "pexp.pdiv_r");
     break;
+
   case isl_ast_op_zdiv_r: // Result only compared against zero
     Res = Builder.CreateSRem(LHS, RHS, "pexp.zdiv_r");
     break;
   }
 
+  // TODO: We can truncate the result, if it fits into a smaller type. This can
+  // help in cases where we have larger operands (e.g. i67) but the result is
+  // known to fit into i64. Without the truncation, the larger i67 type may
+  // force all subsequent operations to be performed on a non-native type.
   isl_ast_expr_free(Expr);
   return Res;
 }
@@ -430,6 +410,7 @@
   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
          "Unsupported unary isl ast expression");
   Value *LHS, *RHS, *Cond;
+  Type *MaxType = getType(Expr);
 
   Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
   if (!Cond->getType()->isIntegerTy(1))
@@ -437,8 +418,17 @@
 
   LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
   RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
-  unifyTypes(LHS, RHS);
 
+  MaxType = getWidestType(MaxType, LHS->getType());
+  MaxType = getWidestType(MaxType, RHS->getType());
+
+  if (MaxType != RHS->getType())
+    RHS = Builder.CreateSExt(RHS, MaxType);
+
+  if (MaxType != LHS->getType())
+    LHS = Builder.CreateSExt(LHS, MaxType);
+
+  // TODO: Do we want to truncate the result?
   isl_ast_expr_free(Expr);
   return Builder.CreateSelect(Cond, LHS, RHS);
 }
@@ -471,7 +461,16 @@
   if (RHSTy->isPointerTy())
     RHS = Builder.CreatePtrToInt(RHS, PtrAsIntTy);
 
-  unifyTypes(LHS, RHS);
+  if (LHS->getType() != RHS->getType()) {
+    Type *MaxType = LHS->getType();
+    MaxType = getWidestType(MaxType, RHS->getType());
+
+    if (MaxType != RHS->getType())
+      RHS = Builder.CreateSExt(RHS, MaxType);
+
+    if (MaxType != LHS->getType())
+      LHS = Builder.CreateSExt(LHS, MaxType);
+  }
 
   isl_ast_op_type OpType = isl_ast_expr_get_op_type(Expr);
   assert(OpType >= isl_ast_op_eq && OpType <= isl_ast_op_gt &&
@@ -677,7 +676,7 @@
 
   V = IDToValue[Id];
   if (!V)
-    V = UndefValue::get(Builder.getInt1Ty());
+    V = UndefValue::get(getType(Expr));
 
   if (V->getType()->isPointerTy())
     V = Builder.CreatePtrToInt(V, Builder.getIntNTy(DL.getPointerSizeInBits()));
@@ -690,12 +689,33 @@
   return V;
 }
 
+IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
+  // XXX: We assume i64 is large enough. This is often true, but in general
+  //      incorrect. Also, on 32bit architectures, it would be beneficial to
+  //      use a smaller type. We can and should directly derive this information
+  //      during code generation.
+  return IntegerType::get(Builder.getContext(), 64);
+}
+
 Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
          "Expression not of type isl_ast_expr_int");
+  isl_val *Val;
+  Value *V;
+  APInt APValue;
+  IntegerType *T;
 
-  auto *Val = isl_ast_expr_get_val(Expr);
-  auto *V = ConstantInt::get(Builder.getContext(), APIntFromVal(Val));
+  Val = isl_ast_expr_get_val(Expr);
+  APValue = APIntFromVal(Val);
+
+  auto BitWidth = APValue.getBitWidth();
+  if (BitWidth <= 64)
+    T = getType(Expr);
+  else
+    T = Builder.getIntNTy(BitWidth);
+
+  APValue = APValue.sextOrSelf(T->getBitWidth());
+  V = ConstantInt::get(T, APValue);
 
   isl_ast_expr_free(Expr);
   return V;
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index b73ed3f..8ef6476 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -390,11 +390,14 @@
   Value *ValueLB = ExprBuilder.create(Init);
   Value *ValueInc = ExprBuilder.create(Inc);
 
-  CmpInst::Predicate Predicate;
-  auto *UB = getUpperBound(For, Predicate);
-  auto *ValueUB = ExprBuilder.create(UB);
+  Type *MaxType = ExprBuilder.getType(Iterator);
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
 
-  ExprBuilder.unifyTypes(ValueLB, ValueUB, ValueInc);
+  if (MaxType != ValueLB->getType())
+    ValueLB = Builder.CreateSExt(ValueLB, MaxType);
+  if (MaxType != ValueInc->getType())
+    ValueInc = Builder.CreateSExt(ValueInc, MaxType);
 
   std::vector<Value *> IVS(VectorWidth);
   IVS[0] = ValueLB;
@@ -442,6 +445,7 @@
   isl_ast_expr *Init, *Inc, *Iterator, *UB;
   isl_id *IteratorID;
   Value *ValueLB, *ValueUB, *ValueInc;
+  Type *MaxType;
   BasicBlock *ExitBlock;
   Value *IV;
   CmpInst::Predicate Predicate;
@@ -468,7 +472,17 @@
   ValueUB = ExprBuilder.create(UB);
   ValueInc = ExprBuilder.create(Inc);
 
-  ExprBuilder.unifyTypes(ValueLB, ValueUB, ValueInc);
+  MaxType = ExprBuilder.getType(Iterator);
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
+
+  if (MaxType != ValueLB->getType())
+    ValueLB = Builder.CreateSExt(ValueLB, MaxType);
+  if (MaxType != ValueUB->getType())
+    ValueUB = Builder.CreateSExt(ValueUB, MaxType);
+  if (MaxType != ValueInc->getType())
+    ValueInc = Builder.CreateSExt(ValueInc, MaxType);
 
   // If we can show that LB <Predicate> UB holds at least once, we can
   // omit the GuardBB in front of the loop.
@@ -540,6 +554,7 @@
   isl_ast_expr *Init, *Inc, *Iterator, *UB;
   isl_id *IteratorID;
   Value *ValueLB, *ValueUB, *ValueInc;
+  Type *MaxType;
   Value *IV;
   CmpInst::Predicate Predicate;
 
@@ -568,7 +583,17 @@
     ValueUB = Builder.CreateAdd(
         ValueUB, Builder.CreateSExt(Builder.getTrue(), ValueUB->getType()));
 
-  ExprBuilder.unifyTypes(ValueLB, ValueUB, ValueInc);
+  MaxType = ExprBuilder.getType(Iterator);
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
+
+  if (MaxType != ValueLB->getType())
+    ValueLB = Builder.CreateSExt(ValueLB, MaxType);
+  if (MaxType != ValueUB->getType())
+    ValueUB = Builder.CreateSExt(ValueUB, MaxType);
+  if (MaxType != ValueInc->getType())
+    ValueInc = Builder.CreateSExt(ValueInc, MaxType);
 
   BasicBlock::iterator LoopBody;
 
diff --git a/polly/lib/CodeGen/LoopGenerators.cpp b/polly/lib/CodeGen/LoopGenerators.cpp
index 960e0cc..566e460 100644
--- a/polly/lib/CodeGen/LoopGenerators.cpp
+++ b/polly/lib/CodeGen/LoopGenerators.cpp
@@ -61,8 +61,6 @@
   assert(LB->getType() == UB->getType() && "Types of loop bounds do not match");
   IntegerType *LoopIVType = dyn_cast<IntegerType>(UB->getType());
   assert(LoopIVType && "UB is not integer?");
-  assert((LoopIVType == LB->getType() && LoopIVType == Stride->getType()) &&
-         "LB, UB and Stride should have equal types.");
 
   BasicBlock *BeforeBB = Builder.GetInsertBlock();
   BasicBlock *GuardBB =
@@ -123,6 +121,7 @@
   Builder.SetInsertPoint(HeaderBB);
   PHINode *IV = Builder.CreatePHI(LoopIVType, 2, "polly.indvar");
   IV->addIncoming(LB, PreHeaderBB);
+  Stride = Builder.CreateZExtOrBitCast(Stride, LoopIVType);
   Value *IncrementedIV = Builder.CreateNSWAdd(IV, Stride, "polly.indvar_next");
   Value *LoopCondition;
   UB = Builder.CreateSub(UB, Stride, "polly.adjust_ub");
@@ -148,12 +147,6 @@
 Value *ParallelLoopGenerator::createParallelLoop(
     Value *LB, Value *UB, Value *Stride, SetVector<Value *> &UsedValues,
     ValueMapT &Map, BasicBlock::iterator *LoopBody) {
-
-  // Adjust the types to match the GOMP API.
-  LB = Builder.CreateSExt(LB, LongType);
-  UB = Builder.CreateSExt(UB, LongType);
-  Stride = Builder.CreateSExt(Stride, LongType);
-
   Function *SubFn;
 
   AllocaInst *Struct = storeValuesIntoStruct(UsedValues);