aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2021-02-26 16:48:58 +0300
committerRoman Lebedev <lebedev.ri@gmail.com>2021-03-06 21:52:46 +0300
commitb46c085d2b6d15873fb53718f0a70b3848e19e4a (patch)
tree59738a0d0244c509d4f2fa921a9b5c7b115ec3a3 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parentf0904a62085aa84737e7e6f2a2318cda0d52c371 (diff)
downloadllvm-b46c085d2b6d15873fb53718f0a70b3848e19e4a.zip
llvm-b46c085d2b6d15873fb53718f0a70b3848e19e4a.tar.gz
llvm-b46c085d2b6d15873fb53718f0a70b3848e19e4a.tar.bz2
[NFCI] SCEVExpander: emit intrinsics for integral {u,s}{min,max} SCEV expressions
These intrinsics, not the icmp+select are the canonical form nowadays, so we might as well directly emit them. This should not cause any regressions, but if it does, then then they would needed to be fixed regardless. Note that this doesn't deal with `SCEVExpander::isHighCostExpansion()`, but that is a pessimization, not a correctness issue. Additionally, the non-intrinsic form has issues with undef, see https://reviews.llvm.org/D88287#2587863
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp41
1 files changed, 33 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 849ca24..2c9b4cb 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1715,8 +1715,14 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpSGT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::smax, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "smax");
+ else {
+ Value *ICmp = Builder.CreateICmpSGT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1738,8 +1744,14 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpUGT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::umax, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "umax");
+ else {
+ Value *ICmp = Builder.CreateICmpUGT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1761,8 +1773,14 @@ Value *SCEVExpander::visitSMinExpr(const SCEVSMinExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpSLT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smin");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::smin, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "smin");
+ else {
+ Value *ICmp = Builder.CreateICmpSLT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smin");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1784,8 +1802,14 @@ Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpULT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umin");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::umin, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "umin");
+ else {
+ Value *ICmp = Builder.CreateICmpULT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umin");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -2262,6 +2286,7 @@ template<typename T> static InstructionCost costAndCollectOperands(
case scUMaxExpr:
case scSMinExpr:
case scUMinExpr: {
+ // FIXME: should this ask the cost for Intrinsic's?
Cost += CmpSelCost(Instruction::ICmp, S->getNumOperands() - 1, 0, 1);
Cost += CmpSelCost(Instruction::Select, S->getNumOperands() - 1, 0, 2);
break;