Skip to content

Commit a0a9c9e

Browse files
committed
[InstCombine] avoid breaking up min/max (cmp+sel) idioms
This is a quick fix for a motivating case that looks like this: https://godbolt.org/z/GeMqzMc38 As noted, we might be able to restore the min/max patterns with select folds, or we just wait for this to become easier with canonicalization to min/max intrinsics.
1 parent 5bf4ab0 commit a0a9c9e

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5755,9 +5755,6 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
57555755
if (Instruction *Res = foldICmpWithDominatingICmp(I))
57565756
return Res;
57575757

5758-
if (Instruction *Res = foldICmpBinOp(I, Q))
5759-
return Res;
5760-
57615758
if (Instruction *Res = foldICmpUsingKnownBits(I))
57625759
return Res;
57635760

@@ -5803,6 +5800,15 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
58035800
}
58045801
}
58055802

5803+
// The folds in here may rely on wrapping flags and special constants, so
5804+
// they can break up min/max idioms in some cases but not seemingly similar
5805+
// patterns.
5806+
// FIXME: It may be possible to enhance select folding to make this
5807+
// unnecessary. It may also be moot if we canonicalize to min/max
5808+
// intrinsics.
5809+
if (Instruction *Res = foldICmpBinOp(I, Q))
5810+
return Res;
5811+
58065812
if (Instruction *Res = foldICmpInstWithConstant(I))
58075813
return Res;
58085814

llvm/test/Transforms/InstCombine/icmp-add.ll

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -972,17 +972,16 @@ define i1 @slt_offset_nsw(i8 %a, i8 %c) {
972972
ret i1 %ov
973973
}
974974

975-
; FIXME:
976975
; In the following 4 tests, we could push the inc/dec
977976
; through the min/max, but we should not break up the
978977
; min/max idiom by using different icmp and select
979978
; operands.
980979

981980
define i32 @increment_max(i32 %x) {
982981
; CHECK-LABEL: @increment_max(
983-
; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 1
984-
; CHECK-NEXT: [[C_INV:%.*]] = icmp slt i32 [[X]], 0
985-
; CHECK-NEXT: [[S:%.*]] = select i1 [[C_INV]], i32 0, i32 [[A]]
982+
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -1
983+
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -1
984+
; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[TMP2]], 1
986985
; CHECK-NEXT: ret i32 [[S]]
987986
;
988987
%a = add nsw i32 %x, 1
@@ -1019,9 +1018,9 @@ define i32 @increment_min(i32 %x) {
10191018

10201019
define i32 @decrement_min(i32 %x) {
10211020
; CHECK-LABEL: @decrement_min(
1022-
; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], -1
1023-
; CHECK-NEXT: [[C_INV:%.*]] = icmp sgt i32 [[X]], 0
1024-
; CHECK-NEXT: [[S:%.*]] = select i1 [[C_INV]], i32 0, i32 [[A]]
1021+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
1022+
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 1
1023+
; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[TMP2]], -1
10251024
; CHECK-NEXT: ret i32 [[S]]
10261025
;
10271026
%a = add nsw i32 %x, -1

0 commit comments

Comments
 (0)