diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2021-02-26 16:48:58 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2021-03-06 21:52:46 +0300 |
commit | b46c085d2b6d15873fb53718f0a70b3848e19e4a (patch) | |
tree | 59738a0d0244c509d4f2fa921a9b5c7b115ec3a3 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | |
parent | f0904a62085aa84737e7e6f2a2318cda0d52c371 (diff) | |
download | llvm-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.cpp | 41 |
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; |