Skip to content

Commit 65de414

Browse files
committed
[InstCombine] Fold (X / C) cmp X and (X >> C) cmp X into X cmp 0
1 parent 6393ea9 commit 65de414

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "InstCombineInternal.h"
14+
#include "llvm/ADT/APInt.h"
1415
#include "llvm/ADT/APSInt.h"
1516
#include "llvm/ADT/ScopeExit.h"
1617
#include "llvm/ADT/SetVector.h"
@@ -23,6 +24,7 @@
2324
#include "llvm/Analysis/VectorUtils.h"
2425
#include "llvm/IR/ConstantRange.h"
2526
#include "llvm/IR/DataLayout.h"
27+
#include "llvm/IR/Instructions.h"
2628
#include "llvm/IR/IntrinsicInst.h"
2729
#include "llvm/IR/PatternMatch.h"
2830
#include "llvm/Support/KnownBits.h"
@@ -7103,6 +7105,34 @@ Instruction *InstCombinerImpl::foldICmpCommutative(ICmpInst::Predicate Pred,
71037105
if (Value *V = foldICmpWithLowBitMaskedVal(Pred, Op0, Op1, Q, *this))
71047106
return replaceInstUsesWith(CxtI, V);
71057107

7108+
// Folding (X / Y) < X => X > 0 for some constant Y other than 0 or 1
7109+
{
7110+
const APInt *Divisor;
7111+
Value *Dividend;
7112+
if (match(Op0, m_UDiv(m_Value(Dividend), m_APInt(Divisor))) &&
7113+
Op1 == Dividend && Divisor->ugt(1)) {
7114+
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Dividend,
7115+
Constant::getNullValue(Dividend->getType()));
7116+
}
7117+
7118+
if (match(Op0, m_SDiv(m_Value(Dividend), m_APInt(Divisor))) &&
7119+
Op1 == Dividend && Divisor->ugt(1) && !ICmpInst::isUnsigned(Pred)) {
7120+
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Dividend,
7121+
Constant::getNullValue(Dividend->getType()));
7122+
}
7123+
}
7124+
7125+
// Another case of this fold is (X >> Y) < X => X > 0 if Y != 0
7126+
{
7127+
const APInt *Shift;
7128+
Value *V;
7129+
if (match(Op0, m_LShr(m_Value(V), m_APInt(Shift))) && Op1 == V &&
7130+
Shift->ugt(0) && !ICmpInst::isUnsigned(Pred)) {
7131+
return new ICmpInst(ICmpInst::getInversePredicate(Pred), V,
7132+
Constant::getNullValue(V->getType()));
7133+
}
7134+
}
7135+
71067136
return nullptr;
71077137
}
71087138

llvm/test/Transforms/InstCombine/icmp-div-constant.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,7 @@ define i1 @sdiv_eq_smin_use(i32 %x, i32 %y) {
381381

382382
define i1 @sdiv_x_by_const_cmp_x(i32 %x) {
383383
; CHECK-LABEL: @sdiv_x_by_const_cmp_x(
384-
; CHECK-NEXT: [[V:%.*]] = udiv i32 [[X:%.*]], 13
385-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[V]], [[X]]
384+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 0
386385
; CHECK-NEXT: ret i1 [[TMP1]]
387386
;
388387
%v = udiv i32 %x, 13
@@ -392,8 +391,7 @@ define i1 @sdiv_x_by_const_cmp_x(i32 %x) {
392391

393392
define i1 @udiv_x_by_const_cmp_x(i32 %x) {
394393
; CHECK-LABEL: @udiv_x_by_const_cmp_x(
395-
; CHECK-NEXT: [[TMP2:%.*]] = udiv i32 [[X:%.*]], 123
396-
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP2]], [[X]]
394+
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], 0
397395
; CHECK-NEXT: ret i1 [[TMP1]]
398396
;
399397
%1 = udiv i32 %x, 123
@@ -405,8 +403,7 @@ define i1 @udiv_x_by_const_cmp_x(i32 %x) {
405403

406404
define i1 @lshr_x_by_const_cmp_x(i32 %x) {
407405
; CHECK-LABEL: @lshr_x_by_const_cmp_x(
408-
; CHECK-NEXT: [[V:%.*]] = lshr i32 [[X:%.*]], 1
409-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[V]], [[X]]
406+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 0
410407
; CHECK-NEXT: ret i1 [[TMP1]]
411408
;
412409
%v = lshr i32 %x, 1

0 commit comments

Comments
 (0)