From: Nikita Popov Date: Tue, 16 Apr 2019 20:31:41 +0000 (+0000) Subject: [CVP] Simplify umulo and smulo that cannot overflow X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=28e34c70efb9acd3c5c52e6630ec6cb73ff4b14e;p=llvm [CVP] Simplify umulo and smulo that cannot overflow If a umul.with.overflow or smul.with.overflow operation cannot overflow, simplify it to a simple mul nuw / mul nsw. After the refactoring in D60668 this is just a matter of removing an explicit check against multiplications. Differential Revision: https://reviews.llvm.org/D60791 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358521 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index bc4daf1c9c1..b650971624a 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -400,15 +400,10 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI, // See if we can prove that the given overflow intrinsic will not overflow. static bool willNotOverflow(WithOverflowInst *WO, LazyValueInfo *LVI) { - // TODO: Also support multiplication. - Instruction::BinaryOps BinOp = WO->getBinaryOp(); - if (BinOp == Instruction::Mul) - return false; - Value *RHS = WO->getRHS(); ConstantRange RRange = LVI->getConstantRange(RHS, WO->getParent(), WO); ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion( - BinOp, RRange, WO->getNoWrapKind()); + WO->getBinaryOp(), RRange, WO->getNoWrapKind()); // As an optimization, do not compute LRange if we do not need it. if (NWRegion.isEmptySet()) return false; diff --git a/test/Transforms/CorrelatedValuePropagation/overflows.ll b/test/Transforms/CorrelatedValuePropagation/overflows.ll index ed020124279..db758b8459b 100644 --- a/test/Transforms/CorrelatedValuePropagation/overflows.ll +++ b/test/Transforms/CorrelatedValuePropagation/overflows.ll @@ -507,9 +507,11 @@ define i32 @unsigned_mul(i32 %x) { ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 10000 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]] ; CHECK: cond.false: -; CHECK-NEXT: [[MULO:%.*]] = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[X]], i32 100) -; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[MULO]], 0 -; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[MULO]], 1 +; CHECK-NEXT: [[MULO1:%.*]] = mul nuw i32 [[X]], 100 +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i32, i1 } undef, i32 [[MULO1]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } [[TMP0]], i1 false, 1 +; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]] ; CHECK: trap: ; CHECK-NEXT: tail call void @llvm.trap() @@ -545,9 +547,11 @@ define i32 @signed_mul(i32 %x) { ; CHECK-NEXT: [[CMP3:%.*]] = or i1 [[CMP1]], [[CMP2]] ; CHECK-NEXT: br i1 [[CMP3]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]] ; CHECK: cond.false: -; CHECK-NEXT: [[MULO:%.*]] = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[X]], i32 100) -; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[MULO]], 0 -; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[MULO]], 1 +; CHECK-NEXT: [[MULO1:%.*]] = mul nsw i32 [[X]], 100 +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i32, i1 } undef, i32 [[MULO1]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } [[TMP0]], i1 false, 1 +; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]] ; CHECK: trap: ; CHECK-NEXT: tail call void @llvm.trap()