diff options
Diffstat (limited to 'polly/lib')
-rw-r--r-- | polly/lib/CodeGen/IslExprBuilder.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/polly/lib/CodeGen/IslExprBuilder.cpp b/polly/lib/CodeGen/IslExprBuilder.cpp index 4dd7ba3c9a1..12096eaa194 100644 --- a/polly/lib/CodeGen/IslExprBuilder.cpp +++ b/polly/lib/CodeGen/IslExprBuilder.cpp @@ -175,9 +175,33 @@ Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) { LHS = create(isl_ast_expr_get_op_arg(Expr, 0)); RHS = create(isl_ast_expr_get_op_arg(Expr, 1)); + Type *LHSType = LHS->getType(); + Type *RHSType = RHS->getType(); - MaxType = LHS->getType(); - MaxType = getWidestType(MaxType, RHS->getType()); + // Handle <pointer> +/- <integer> and <integer> +/- <pointer> + if (LHSType->isPointerTy() || RHSType->isPointerTy()) { + isl_ast_expr_free(Expr); + + assert((LHSType->isIntegerTy() || RHSType->isIntegerTy()) && + "Arithmetic operations might only performed on one but not two " + "pointer types."); + + if (LHSType->isIntegerTy()) + std::swap(LHS, RHS); + + switch (OpType) { + default: + llvm_unreachable( + "Only additive binary operations are allowed on pointer types."); + case isl_ast_op_sub: + RHS = Builder.CreateNeg(RHS); + // Fall through + case isl_ast_op_add: + return Builder.CreateGEP(LHS, RHS); + } + } + + MaxType = getWidestType(LHSType, RHSType); // Take the result into account when calculating the widest type. // |