Skip to content

Commit 0f9ed0e

Browse files
committed
[InstCombine] handle (X + A) % Op1 for small X, A
1 parent a96c87c commit 0f9ed0e

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,6 +2461,24 @@ Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {
24612461
}
24622462
}
24632463

2464+
// For "(X + A) % Op1" and if (X u< Op1 && A u< Op1)
2465+
// => (X + A) >= Op1 ? X + A - Op1 : X + A .
2466+
Value *A = nullptr;
2467+
if (match(Op0, m_Add(m_Value(X), m_Value(A)))) {
2468+
Value *Val_X =
2469+
simplifyICmpInst(ICmpInst::ICMP_ULT, X, Op1, SQ.getWithInstruction(&I));
2470+
Value *Val_A =
2471+
simplifyICmpInst(ICmpInst::ICMP_ULT, A, Op1, SQ.getWithInstruction(&I));
2472+
if (Val_X && match(Val_X, m_One()) && Val_A && match(Val_A, m_One())) {
2473+
Value *FrozenOp0 = Op0;
2474+
if (!isGuaranteedNotToBeUndef(Op0))
2475+
FrozenOp0 = Builder.CreateFreeze(Op0, Op0->getName() + ".frozen");
2476+
Value *Cmp = Builder.CreateICmpUGE(FrozenOp0, Op1);
2477+
Value *Sub = Builder.CreateSub(FrozenOp0, Op1);
2478+
return SelectInst::Create(Cmp, Sub, FrozenOp0);
2479+
}
2480+
}
2481+
24642482
return nullptr;
24652483
}
24662484

llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ define i8 @urem_assume_a(i8 %x, i8 %n, i8 %a) {
2727
; CHECK-NEXT: [[CMP_A:%.*]] = icmp ult i8 [[A:%.*]], [[N]]
2828
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP_A]])
2929
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X_FR]], [[A]]
30-
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
30+
; CHECK-NEXT: [[ADD_FROZEN:%.*]] = freeze i8 [[ADD]]
31+
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ult i8 [[ADD_FROZEN]], [[N]]
32+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTNOT]], i8 0, i8 [[N]]
33+
; CHECK-NEXT: [[OUT:%.*]] = sub i8 [[ADD_FROZEN]], [[TMP1]]
3134
; CHECK-NEXT: ret i8 [[OUT]]
3235
;
3336
%cmp = icmp ult i8 %x, %n
@@ -231,7 +234,10 @@ define i8 @urem_without_assume_a(i8 %arg, i8 %arg2, i8 %a) {
231234
; CHECK-NEXT: [[X_REM:%.*]] = urem i8 [[ARG:%.*]], [[ARG2:%.*]]
232235
; CHECK-NEXT: [[A_REM:%.*]] = urem i8 [[A:%.*]], [[ARG2]]
233236
; CHECK-NEXT: [[ADDD:%.*]] = add i8 [[X_REM]], [[A_REM]]
234-
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADDD]], [[ARG2]]
237+
; CHECK-NEXT: [[ADD_FROZEN:%.*]] = freeze i8 [[ADDD]]
238+
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ult i8 [[ADD_FROZEN]], [[ARG2]]
239+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTNOT]], i8 0, i8 [[ARG2]]
240+
; CHECK-NEXT: [[OUT:%.*]] = sub i8 [[ADD_FROZEN]], [[TMP1]]
235241
; CHECK-NEXT: ret i8 [[OUT]]
236242
;
237243
%x_rem = urem i8 %arg, %arg2

0 commit comments

Comments
 (0)