diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -546,6 +546,20 @@ return Known; } +static void remGetLowBits(KnownBits &Known, const KnownBits &LHS, + const KnownBits &RHS) { + if (!RHS.isZero() && RHS.Zero[0]) { + // rem X, Y where Y[0:N] is zero will X[0:N] in the result. + unsigned RHSZeros = RHS.countMinTrailingZeros(); + APInt Mask = APInt::getBitsSet(LHS.getBitWidth(), 0, RHSZeros); + APInt OnesMask = LHS.One & Mask; + APInt ZerosMask = LHS.Zero & Mask; + assert((OnesMask & ZerosMask).isZero()); + Known.One |= OnesMask; + Known.Zero |= ZerosMask; + } +} + KnownBits KnownBits::urem(const KnownBits &LHS, const KnownBits &RHS) { unsigned BitWidth = LHS.getBitWidth(); assert(!LHS.hasConflict() && !RHS.hasConflict()); @@ -559,6 +573,8 @@ return Known; } + remGetLowBits(Known, LHS, RHS); + // Since the result is less than or equal to either operand, any leading // zero bits in either operand must also exist in the result. uint32_t Leaders = @@ -590,6 +606,8 @@ return Known; } + remGetLowBits(Known, LHS, RHS); + // The sign bit is the LHS's sign bit, except when the result of the // remainder is zero. The magnitude of the result should be less than or // equal to the magnitude of the LHS. Therefore any leading zeros that exist diff --git a/llvm/test/Analysis/ScalarEvolution/merge-add-rec-many-inputs.ll b/llvm/test/Analysis/ScalarEvolution/merge-add-rec-many-inputs.ll --- a/llvm/test/Analysis/ScalarEvolution/merge-add-rec-many-inputs.ll +++ b/llvm/test/Analysis/ScalarEvolution/merge-add-rec-many-inputs.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s ; Check that isImpliedViaMerge wouldn't crash when trying to prove @@ -60,11 +61,11 @@ %7 = srem i32 %local_7_217, 6 %8 = add i32 %7, 114 switch i32 %8, label %done405 [ - i32 114, label %bci_562 - i32 116, label %bci_304 - i32 117, label %bci_395 - i32 118, label %bci_407 - i32 119, label %bci_419 + i32 114, label %bci_562 + i32 116, label %bci_304 + i32 117, label %bci_395 + i32 118, label %bci_407 + i32 119, label %bci_419 ] bci_419: ; preds = %bci_221 @@ -125,3 +126,5 @@ not_subtype: ; preds = %out_of_bounds br label %bci_604 } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK: {{.*}} diff --git a/llvm/test/Analysis/ValueTracking/knownbits-rem-lowbits.ll b/llvm/test/Analysis/ValueTracking/knownbits-rem-lowbits.ll --- a/llvm/test/Analysis/ValueTracking/knownbits-rem-lowbits.ll +++ b/llvm/test/Analysis/ValueTracking/knownbits-rem-lowbits.ll @@ -3,11 +3,7 @@ define i8 @urem_low_bits_know(i8 %xx, i8 %yy) { ; CHECK-LABEL: @urem_low_bits_know( -; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 2 -; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], -4 -; CHECK-NEXT: [[REM:%.*]] = urem i8 [[X]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], 2 -; CHECK-NEXT: ret i8 [[R]] +; CHECK-NEXT: ret i8 2 ; %x = or i8 %xx, 2 %y = and i8 %yy, -4 @@ -18,12 +14,7 @@ define i8 @urem_low_bits_know2(i8 %xx, i8 %yy) { ; CHECK-LABEL: @urem_low_bits_know2( -; CHECK-NEXT: [[XO:%.*]] = and i8 [[XX:%.*]], -4 -; CHECK-NEXT: [[X:%.*]] = or i8 [[XO]], 2 -; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], -4 -; CHECK-NEXT: [[REM:%.*]] = urem i8 [[X]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], 3 -; CHECK-NEXT: ret i8 [[R]] +; CHECK-NEXT: ret i8 2 ; %xo = or i8 %xx, 2 %x = and i8 %xo, 254 @@ -80,11 +71,7 @@ define i8 @srem_low_bits_know(i8 %xx, i8 %yy) { ; CHECK-LABEL: @srem_low_bits_know( -; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 10 -; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], -4 -; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], 2 -; CHECK-NEXT: ret i8 [[R]] +; CHECK-NEXT: ret i8 2 ; %x = or i8 %xx, 10 %y = and i8 %yy, -4 @@ -95,11 +82,7 @@ define i8 @srem_low_bits_know2(i8 %xx, i8 %yy) { ; CHECK-LABEL: @srem_low_bits_know2( -; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1 -; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], -2 -; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], 1 -; CHECK-NEXT: ret i8 [[R]] +; CHECK-NEXT: ret i8 1 ; %x = or i8 %xx, 1 %y = and i8 %yy, -2 diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/masked-call.ll b/llvm/test/Transforms/LoopVectorize/AArch64/masked-call.ll --- a/llvm/test/Transforms/LoopVectorize/AArch64/masked-call.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/masked-call.ll @@ -33,8 +33,7 @@ ; TFNONE-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; TFNONE-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] ; TFNONE: middle.block: -; TFNONE-NEXT: [[CMP_N:%.*]] = icmp eq i64 1025, [[N_VEC]] -; TFNONE-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; TFNONE-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; TFNONE: scalar.ph: ; TFNONE-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] ; TFNONE-NEXT: br label [[FOR_BODY:%.*]] @@ -193,8 +192,7 @@ ; TFNONE-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; TFNONE-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; TFNONE: middle.block: -; TFNONE-NEXT: [[CMP_N:%.*]] = icmp eq i64 1025, [[N_VEC]] -; TFNONE-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; TFNONE-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; TFNONE: scalar.ph: ; TFNONE-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] ; TFNONE-NEXT: br label [[FOR_BODY:%.*]] @@ -395,8 +393,7 @@ ; TFNONE-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; TFNONE-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] ; TFNONE: middle.block: -; TFNONE-NEXT: [[CMP_N:%.*]] = icmp eq i64 1025, [[N_VEC]] -; TFNONE-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; TFNONE-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; TFNONE: scalar.ph: ; TFNONE-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] ; TFNONE-NEXT: br label [[FOR_BODY:%.*]] @@ -607,8 +604,7 @@ ; TFNONE-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; TFNONE-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; TFNONE: middle.block: -; TFNONE-NEXT: [[CMP_N:%.*]] = icmp eq i64 1025, [[N_VEC]] -; TFNONE-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; TFNONE-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; TFNONE: scalar.ph: ; TFNONE-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] ; TFNONE-NEXT: br label [[FOR_BODY:%.*]] @@ -666,8 +662,7 @@ ; TFFALLBACK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; TFFALLBACK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; TFFALLBACK: middle.block: -; TFFALLBACK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1025, [[N_VEC]] -; TFFALLBACK-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; TFFALLBACK-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; TFFALLBACK: scalar.ph: ; TFFALLBACK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] ; TFFALLBACK-NEXT: br label [[FOR_BODY:%.*]] @@ -731,8 +726,7 @@ ; TFNONE-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; TFNONE-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] ; TFNONE: middle.block: -; TFNONE-NEXT: [[CMP_N:%.*]] = icmp eq i64 1025, [[N_VEC]] -; TFNONE-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; TFNONE-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; TFNONE: scalar.ph: ; TFNONE-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] ; TFNONE-NEXT: br label [[FOR_BODY:%.*]]