Skip to content

Commit 23099ac

Browse files
authored
Add known and demanded bits support for zext nneg (#70858)
zext nneg was recently added to the IR in #67982. This patch teaches demanded bits and known bits about the semantics of the instruction, and adds a couple of test cases to illustrate basic functionality.
1 parent 6846258 commit 23099ac

File tree

4 files changed

+13
-9
lines changed

4 files changed

+13
-9
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,9 @@ static void computeKnownBitsFromOperator(const Operator *I,
11031103
assert(SrcBitWidth && "SrcBitWidth can't be zero");
11041104
Known = Known.anyextOrTrunc(SrcBitWidth);
11051105
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
1106+
if (auto *Inst = dyn_cast<PossiblyNonNegInst>(I);
1107+
Inst && Inst->hasNonNeg() && !Known.isNegative())
1108+
Known.makeNonNegative();
11061109
Known = Known.zextOrTrunc(BitWidth);
11071110
break;
11081111
}

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
429429
return I;
430430
}
431431
assert(InputKnown.getBitWidth() == SrcBitWidth && "Src width changed?");
432+
if (I->getOpcode() == Instruction::ZExt && I->hasNonNeg() &&
433+
!InputKnown.isNegative())
434+
InputKnown.makeNonNegative();
432435
Known = InputKnown.zextOrTrunc(BitWidth);
436+
433437
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
434438
break;
435439
}

llvm/test/Transforms/InstCombine/zext.ll

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -795,9 +795,8 @@ define i16 @zext_nneg_flag_drop(i8 %x, i16 %y) {
795795

796796
define i32 @zext_nneg_redundant_and(i8 %a) {
797797
; CHECK-LABEL: @zext_nneg_redundant_and(
798-
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 127
799-
; CHECK-NEXT: [[RES:%.*]] = zext i8 [[TMP1]] to i32
800-
; CHECK-NEXT: ret i32 [[RES]]
798+
; CHECK-NEXT: [[A_I32:%.*]] = zext nneg i8 [[A:%.*]] to i32
799+
; CHECK-NEXT: ret i32 [[A_I32]]
801800
;
802801
%a.i32 = zext nneg i8 %a to i32
803802
%res = and i32 %a.i32, 127
@@ -818,9 +817,7 @@ define i32 @zext_nneg_redundant_and_neg(i8 %a) {
818817

819818
define i64 @zext_nneg_signbit_extract(i32 %a) nounwind {
820819
; CHECK-LABEL: @zext_nneg_signbit_extract(
821-
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[A:%.*]], 31
822-
; CHECK-NEXT: [[C:%.*]] = zext i32 [[TMP1]] to i64
823-
; CHECK-NEXT: ret i64 [[C]]
820+
; CHECK-NEXT: ret i64 0
824821
;
825822
%b = zext nneg i32 %a to i64
826823
%c = lshr i64 %b, 31
@@ -831,7 +828,7 @@ define i64 @zext_nneg_demanded_constant(i8 %a) nounwind {
831828
; CHECK-LABEL: @zext_nneg_demanded_constant(
832829
; CHECK-NEXT: [[B:%.*]] = zext nneg i8 [[A:%.*]] to i64
833830
; CHECK-NEXT: call void @use64(i64 [[B]]) #[[ATTR0:[0-9]+]]
834-
; CHECK-NEXT: [[C:%.*]] = and i64 [[B]], 254
831+
; CHECK-NEXT: [[C:%.*]] = and i64 [[B]], 126
835832
; CHECK-NEXT: ret i64 [[C]]
836833
;
837834
%b = zext nneg i8 %a to i64

llvm/test/Transforms/LoopVectorize/reduction.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ define i64 @reduction_with_phi_with_one_incoming_on_backedge(i16 %n, ptr %A) {
12041204
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i16 [[SMAX]], 5
12051205
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
12061206
; CHECK: vector.ph:
1207-
; CHECK-NEXT: [[N_VEC:%.*]] = and i32 [[TMP1]], 65532
1207+
; CHECK-NEXT: [[N_VEC:%.*]] = and i32 [[TMP1]], 32764
12081208
; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i16
12091209
; CHECK-NEXT: [[IND_END:%.*]] = or i16 [[DOTCAST]], 1
12101210
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -1282,7 +1282,7 @@ define i64 @reduction_with_phi_with_two_incoming_on_backedge(i16 %n, ptr %A) {
12821282
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i16 [[SMAX]], 5
12831283
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
12841284
; CHECK: vector.ph:
1285-
; CHECK-NEXT: [[N_VEC:%.*]] = and i32 [[TMP1]], 65532
1285+
; CHECK-NEXT: [[N_VEC:%.*]] = and i32 [[TMP1]], 32764
12861286
; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i16
12871287
; CHECK-NEXT: [[IND_END:%.*]] = or i16 [[DOTCAST]], 1
12881288
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]

0 commit comments

Comments
 (0)