Skip to content

Commit ea0bafd

Browse files
committed
[CVP] Remove some {s|u}sub.with.overflow checks.
This uses ConstantRange::makeGuaranteedNoWrapRegion's newly-added handling for subtraction to allow CVP to remove some subtraction overflow checks. Differential Revision: https://reviews.llvm.org/D40039 llvm-svn: 319807
1 parent c32b0fc commit ea0bafd

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

+17-8
Original file line numberDiff line numberDiff line change
@@ -329,25 +329,29 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI) {
329329
// See if we can prove that the given overflow intrinsic will not overflow.
330330
static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) {
331331
using OBO = OverflowingBinaryOperator;
332-
auto NoWrapOnAddition = [&] (Value *LHS, Value *RHS, unsigned NoWrapKind) {
332+
auto NoWrap = [&] (Instruction::BinaryOps BinOp, unsigned NoWrapKind) {
333+
Value *RHS = II->getOperand(1);
333334
ConstantRange RRange = LVI->getConstantRange(RHS, II->getParent(), II);
334335
ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
335-
BinaryOperator::Add, RRange, NoWrapKind);
336+
BinOp, RRange, NoWrapKind);
336337
// As an optimization, do not compute LRange if we do not need it.
337338
if (NWRegion.isEmptySet())
338339
return false;
340+
Value *LHS = II->getOperand(0);
339341
ConstantRange LRange = LVI->getConstantRange(LHS, II->getParent(), II);
340342
return NWRegion.contains(LRange);
341343
};
342344
switch (II->getIntrinsicID()) {
343345
default:
344346
break;
345347
case Intrinsic::uadd_with_overflow:
346-
return NoWrapOnAddition(II->getOperand(0), II->getOperand(1),
347-
OBO::NoUnsignedWrap);
348+
return NoWrap(Instruction::Add, OBO::NoUnsignedWrap);
348349
case Intrinsic::sadd_with_overflow:
349-
return NoWrapOnAddition(II->getOperand(0), II->getOperand(1),
350-
OBO::NoSignedWrap);
350+
return NoWrap(Instruction::Add, OBO::NoSignedWrap);
351+
case Intrinsic::usub_with_overflow:
352+
return NoWrap(Instruction::Sub, OBO::NoUnsignedWrap);
353+
case Intrinsic::ssub_with_overflow:
354+
return NoWrap(Instruction::Sub, OBO::NoSignedWrap);
351355
}
352356
return false;
353357
}
@@ -356,12 +360,17 @@ static void processOverflowIntrinsic(IntrinsicInst *II) {
356360
Value *NewOp = nullptr;
357361
switch (II->getIntrinsicID()) {
358362
default:
359-
llvm_unreachable("Illegal instruction.");
363+
llvm_unreachable("Unexpected instruction.");
360364
case Intrinsic::uadd_with_overflow:
361365
case Intrinsic::sadd_with_overflow:
362366
NewOp = BinaryOperator::CreateAdd(II->getOperand(0), II->getOperand(1),
363367
II->getName(), II);
364368
break;
369+
case Intrinsic::usub_with_overflow:
370+
case Intrinsic::ssub_with_overflow:
371+
NewOp = BinaryOperator::CreateSub(II->getOperand(0), II->getOperand(1),
372+
II->getName(), II);
373+
break;
365374
}
366375
++NumOverflows;
367376
IRBuilder<> B(II);
@@ -376,7 +385,7 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
376385
SmallVector<unsigned, 4> ArgNos;
377386
unsigned ArgNo = 0;
378387

379-
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
388+
if (auto *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
380389
if (willNotOverflow(II, LVI)) {
381390
processOverflowIntrinsic(II);
382391
return true;

llvm/test/Transforms/CorrelatedValuePropagation/overflows.ll

+6-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ declare void @llvm.trap()
1313

1414
define i32 @signed_add(i32 %x, i32 %y) {
1515
; CHECK-LABEL: @signed_add(
16-
; CHECK: @llvm.ssub.with.overflow.i32
17-
; CHECK: @llvm.ssub.with.overflow.i32
16+
; CHECK-NOT: @llvm.ssub.with.overflow.i32
1817
; CHECK: @llvm.sadd.with.overflow.i32
1918
entry:
2019
%cmp = icmp sgt i32 %y, 0
@@ -61,7 +60,7 @@ cond.end: ; preds = %cond.false, %cont,
6160

6261
define i32 @unsigned_add(i32 %x, i32 %y) {
6362
; CHECK-LABEL: @unsigned_add(
64-
; CHECK: @llvm.usub.with.overflow.i32
63+
; CHECK-NOT: @llvm.usub.with.overflow.i32
6564
; CHECK: @llvm.uadd.with.overflow.i32
6665
entry:
6766
%0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
@@ -203,7 +202,7 @@ cond.end: ; preds = %cond.false, %entry
203202

204203
define i32 @signed_sub_r1(i32 %x) {
205204
; CHECK-LABEL: @signed_sub_r1(
206-
; CHECK: @llvm.ssub.with.overflow.i32
205+
; CHECK-NOT: @llvm.ssub.with.overflow.i32
207206
entry:
208207
%cmp = icmp eq i32 %x, -2147483648
209208
br i1 %cmp, label %cond.end, label %cond.false
@@ -225,7 +224,7 @@ cond.end: ; preds = %cond.false, %entry
225224

226225
define i32 @unsigned_sub_r1(i32 %x) {
227226
; CHECK-LABEL: @unsigned_sub_r1(
228-
; CHECK: @llvm.usub.with.overflow.i32
227+
; CHECK-NOT: @llvm.usub.with.overflow.i32
229228
entry:
230229
%cmp = icmp eq i32 %x, 0
231230
br i1 %cmp, label %cond.end, label %cond.false
@@ -269,7 +268,7 @@ cond.end: ; preds = %cond.false, %entry
269268

270269
define i32 @signed_sub_rn1(i32 %x) {
271270
; CHECK-LABEL: @signed_sub_rn1(
272-
; CHECK: @llvm.ssub.with.overflow.i32
271+
; CHECK-NOT: @llvm.ssub.with.overflow.i32
273272
entry:
274273
%cmp = icmp eq i32 %x, 2147483647
275274
br i1 %cmp, label %cond.end, label %cond.false
@@ -293,7 +292,7 @@ declare i32 @bar(i32)
293292

294293
define void @unsigned_loop(i32 %i) {
295294
; CHECK-LABEL: @unsigned_loop(
296-
; CHECK: @llvm.usub.with.overflow.i32
295+
; CHECK-NOT: @llvm.usub.with.overflow.i32
297296
entry:
298297
%cmp3 = icmp eq i32 %i, 0
299298
br i1 %cmp3, label %while.end, label %while.body.preheader

0 commit comments

Comments
 (0)