Recommit: "Simplify min/max expression generation"

As part of this simplification we pull complex logic out of the loop body and
skip the previously redundantly executed first loop iteration.

This is a partial recommit of r271514 and r271535 which where in conflict with
the revert in r272483 and consequently also had to be reverted temporarily.  The
original patch was contributed by Johannes Doerfert.

This patch is mostly a NFC, but dropping the first loop iteration can sometimes
result in slightly simpler code.

llvm-svn: 272502
This commit is contained in:
Tobias Grosser 2016-06-12 04:49:41 +00:00
parent c0a5fa0a07
commit 43de17872a
1 changed files with 16 additions and 21 deletions

View File

@ -171,14 +171,22 @@ Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
"We need at least two operands in an n-ary operation");
Value *V;
CmpInst::Predicate Pred;
switch (isl_ast_expr_get_op_type(Expr)) {
default:
llvm_unreachable("This is not a an n-ary isl ast expression");
case isl_ast_op_max:
Pred = CmpInst::ICMP_SGT;
break;
case isl_ast_op_min:
Pred = CmpInst::ICMP_SLT;
break;
}
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));
Value *V = create(isl_ast_expr_get_op_arg(Expr, 0));
for (int i = 1; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
Value *OpV = create(isl_ast_expr_get_op_arg(Expr, i));
Type *Ty = getWidestType(V->getType(), OpV->getType());
if (Ty != OpV->getType())
@ -187,21 +195,8 @@ Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
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;
}
}
Value *Cmp = Builder.CreateICmp(Pred, V, OpV);
V = Builder.CreateSelect(Cmp, V, OpV);
}
// TODO: We can truncate the result, if it fits into a smaller type. This can