[InstCombine] limit zext-of-icmp folds to bit-hacks

In the changed tests, we avoid creating extra instructions,
and there are no obvious regressions in IR tests at least.

Codegen should be able to create the shift+mask form if that
is profitable.

This is a more general fix for issue #59897 than 0eedc9e567 .
This commit is contained in:
Sanjay Patel
2023-01-09 16:29:24 -05:00
parent a4f3b23671
commit f400daae90
2 changed files with 9 additions and 11 deletions

View File

@@ -1024,7 +1024,9 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp,
// zext (X == 0) to i32 --> (X>>1)^1 iff X has only the 2nd bit set.
// zext (X != 0) to i32 --> X iff X has only the low bit set.
// zext (X != 0) to i32 --> X>>1 iff X has only the 2nd bit set.
if (Op1CV->isZero() && Cmp->isEquality()) {
if (Op1CV->isZero() && Cmp->isEquality() &&
(Cmp->getOperand(0)->getType() == Zext.getType() ||
Cmp->getPredicate() == ICmpInst::ICMP_NE)) {
// If Op1C some other power of two, convert:
KnownBits Known = computeKnownBits(Cmp->getOperand(0), 0, &Zext);

View File

@@ -645,10 +645,9 @@ define i64 @and_trunc_extra_use1_wider_src(i65 %x, i32 %y) {
define i16 @zext_icmp_eq0_pow2(i32 %x) {
; CHECK-LABEL: @zext_icmp_eq0_pow2(
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = lshr i16 [[TMP1]], 2
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP2]], 1
; CHECK-NEXT: [[Z:%.*]] = xor i16 [[TMP3]], 1
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 4
; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[M]], 0
; CHECK-NEXT: [[Z:%.*]] = zext i1 [[I]] to i16
; CHECK-NEXT: ret i16 [[Z]]
;
%m = and i32 %x, 4
@@ -661,9 +660,8 @@ define i16 @zext_icmp_eq0_pow2_use1(i32 %x) {
; CHECK-LABEL: @zext_icmp_eq0_pow2_use1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 4
; CHECK-NEXT: call void @use32(i32 [[M]])
; CHECK-NEXT: [[M_LOBIT:%.*]] = lshr exact i32 [[M]], 2
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[M_LOBIT]] to i16
; CHECK-NEXT: [[Z:%.*]] = xor i16 [[TMP1]], 1
; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[M]], 0
; CHECK-NEXT: [[Z:%.*]] = zext i1 [[I]] to i16
; CHECK-NEXT: ret i16 [[Z]]
;
%m = and i32 %x, 4
@@ -678,9 +676,7 @@ define i16 @zext_icmp_eq0_pow2_use2(i32 %x) {
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 4
; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[M]], 0
; CHECK-NEXT: call void @use1(i1 [[I]])
; CHECK-NEXT: [[M_LOBIT:%.*]] = lshr exact i32 [[M]], 2
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[M_LOBIT]] to i16
; CHECK-NEXT: [[Z:%.*]] = xor i16 [[TMP1]], 1
; CHECK-NEXT: [[Z:%.*]] = zext i1 [[I]] to i16
; CHECK-NEXT: ret i16 [[Z]]
;
%m = and i32 %x, 4