Skip to content

Commit 84cdccc

Browse files
committed
[InstCombine] try to eliminate an instruction in min/max -> abs fold
As suggested in the review thread for 5094e12 and seen in the motivating example from https://llvm.org/PR49885, it's not clear if we have a way to create the optimal code without this heuristic.
1 parent 1667fbe commit 84cdccc

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,12 +916,21 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
916916
// umax(X, -X) --> -abs(X)
917917
// umin(X, -X) --> abs(X)
918918
if (isKnownNegation(I0, I1)) {
919+
// We can choose either operand as the input to abs(), but if we can
920+
// eliminate the only use of a value, that's better for subsequent
921+
// transforms/analysis.
922+
if (I0->hasOneUse() && !I1->hasOneUse())
923+
std::swap(I0, I1);
924+
919925
// This is some variant of abs(). See if we can propagate 'nsw' to the abs
920926
// operation and potentially its negation.
921927
bool IntMinIsPoison = isKnownNegation(I0, I1, /* NeedNSW */ true);
922928
Value *Abs = Builder.CreateBinaryIntrinsic(
923929
Intrinsic::abs, I0,
924930
ConstantInt::getBool(II->getContext(), IntMinIsPoison));
931+
932+
// We don't have a "nabs" intrinsic, so negate if needed based on the
933+
// max/min operation.
925934
if (IID == Intrinsic::smin || IID == Intrinsic::umax)
926935
Abs = Builder.CreateNeg(Abs, "nabs", /* NUW */ false, IntMinIsPoison);
927936
return replaceInstUsesWith(CI, Abs);

llvm/test/Transforms/InstCombine/minmax-intrinsics.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,10 +692,9 @@ define i8 @umin_negation(i8 %x) {
692692

693693
define i8 @smax_negation_uses(i8 %x, i8 %y) {
694694
; CHECK-LABEL: @smax_negation_uses(
695-
; CHECK-NEXT: [[S1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
696-
; CHECK-NEXT: [[S2:%.*]] = sub i8 [[Y]], [[X]]
695+
; CHECK-NEXT: [[S2:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]
697696
; CHECK-NEXT: call void @use(i8 [[S2]])
698-
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[S1]], i1 false)
697+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[S2]], i1 false)
699698
; CHECK-NEXT: ret i8 [[TMP1]]
700699
;
701700
%s1 = sub i8 %x, %y

0 commit comments

Comments
 (0)