Skip to content

Commit 8fc03e4

Browse files
authored
[InstCombine] avoid extra instructions in foldSelectICmpAnd (#127398)
Disable fold when it will result in more instructions.
1 parent 75ea7ae commit 8fc03e4

File tree

2 files changed

+19
-18
lines changed

2 files changed

+19
-18
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,15 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
205205
unsigned ValZeros = ValC.logBase2();
206206
unsigned AndZeros = AndMask.logBase2();
207207
bool ShouldNotVal = !TC.isZero();
208-
209-
// If we would need to create an 'and' + 'shift' + 'xor' to replace a 'select'
210-
// + 'icmp', then this transformation would result in more instructions and
211-
// potentially interfere with other folding.
212-
if (CreateAnd && ShouldNotVal && ValZeros != AndZeros)
208+
bool NeedShift = ValZeros != AndZeros;
209+
bool NeedZExtTrunc =
210+
SelType->getScalarSizeInBits() != V->getType()->getScalarSizeInBits();
211+
212+
// If we would need to create an 'and' + 'shift' + 'xor' + cast to replace
213+
// a 'select' + 'icmp', then this transformation would result in more
214+
// instructions and potentially interfere with other folding.
215+
if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >
216+
1 + Cmp->hasOneUse())
213217
return nullptr;
214218

215219
// Insert the 'and' instruction on the input to the truncate.

llvm/test/Transforms/InstCombine/select-icmp-and.ll

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,8 @@ define i32 @test15e_extra_use(i32 %X) {
391391
;; (a & 128) ? 256 : 0
392392
define i32 @test15e_zext(i8 %X) {
393393
; CHECK-LABEL: @test15e_zext(
394-
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128
395-
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
396-
; CHECK-NEXT: [[T3:%.*]] = shl nuw nsw i32 [[TMP2]], 1
394+
; CHECK-NEXT: [[T2_NOT:%.*]] = icmp sgt i8 [[X:%.*]], -1
395+
; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2_NOT]], i32 0, i32 256
397396
; CHECK-NEXT: ret i32 [[T3]]
398397
;
399398
%t1 = and i8 %X, 128
@@ -406,9 +405,7 @@ define i32 @test15e_zext(i8 %X) {
406405
define i32 @test15e_zext_extra_use(i8 %X) {
407406
; CHECK-LABEL: @test15e_zext_extra_use(
408407
; CHECK-NEXT: [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0
409-
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -128
410-
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
411-
; CHECK-NEXT: [[T3:%.*]] = shl nuw nsw i32 [[TMP2]], 1
408+
; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i32 256, i32 0
412409
; CHECK-NEXT: call void @use1(i1 [[T2]])
413410
; CHECK-NEXT: ret i32 [[T3]]
414411
;
@@ -438,8 +435,7 @@ define i32 @test15f_extra_use(i32 %X) {
438435
; CHECK-LABEL: @test15f_extra_use(
439436
; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 128
440437
; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0
441-
; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[T1]], 1
442-
; CHECK-NEXT: [[T3:%.*]] = xor i32 [[TMP1]], 256
438+
; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i32 0, i32 256
443439
; CHECK-NEXT: call void @use1(i1 [[T2]])
444440
; CHECK-NEXT: ret i32 [[T3]]
445441
;
@@ -453,10 +449,9 @@ define i32 @test15f_extra_use(i32 %X) {
453449
;; (a & 128) ? 0 : 256
454450
define i16 @test15f_trunc(i32 %X) {
455451
; CHECK-LABEL: @test15f_trunc(
456-
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
457-
; CHECK-NEXT: [[TMP2:%.*]] = shl i16 [[TMP1]], 1
458-
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP2]], 256
459-
; CHECK-NEXT: [[T3:%.*]] = xor i16 [[TMP3]], 256
452+
; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 128
453+
; CHECK-NEXT: [[T2_NOT:%.*]] = icmp eq i32 [[T1]], 0
454+
; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2_NOT]], i16 256, i16 0
460455
; CHECK-NEXT: ret i16 [[T3]]
461456
;
462457
%t1 = and i32 %X, 128
@@ -799,7 +794,9 @@ define i8 @select_bittest_to_xor(i8 %x) {
799794
; CHECK-LABEL: @select_bittest_to_xor(
800795
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
801796
; CHECK-NEXT: call void @use1(i1 [[CMP]])
802-
; CHECK-NEXT: [[MASKSEL:%.*]] = xor i8 [[X]], -128
797+
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 127
798+
; CHECK-NEXT: [[MASKSEL1:%.*]] = select i1 [[CMP]], i8 -128, i8 0
799+
; CHECK-NEXT: [[MASKSEL:%.*]] = or disjoint i8 [[AND]], [[MASKSEL1]]
803800
; CHECK-NEXT: ret i8 [[MASKSEL]]
804801
;
805802
%cmp = icmp sgt i8 %x, -1

0 commit comments

Comments
 (0)