STATISTIC(NumUDivs, "Number of udivs whose width was decreased");
STATISTIC(NumAShrs, "Number of ashr converted to lshr");
STATISTIC(NumSRems, "Number of srem converted to urem");
+STATISTIC(NumSExt, "Number of sext converted to zext");
STATISTIC(NumOverflows, "Number of overflow checks removed");
STATISTIC(NumSaturating,
"Number of saturating arithmetics converted to normal arithmetics");
return true;
}
+static bool processSExt(SExtInst *SDI, LazyValueInfo *LVI) {
+ if (SDI->getType()->isVectorTy())
+ return false;
+
+ Value *Base = SDI->getOperand(0);
+
+ Constant *Zero = ConstantInt::get(Base->getType(), 0);
+ if (LVI->getPredicateAt(ICmpInst::ICMP_SGE, Base, Zero, SDI) !=
+ LazyValueInfo::True)
+ return false;
+
+ ++NumSExt;
+ auto *ZExt =
+ CastInst::CreateZExtOrBitCast(Base, SDI->getType(), SDI->getName(), SDI);
+ ZExt->setDebugLoc(SDI->getDebugLoc());
+ SDI->replaceAllUsesWith(ZExt);
+ SDI->eraseFromParent();
+
+ return true;
+}
+
static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) {
using OBO = OverflowingBinaryOperator;
case Instruction::AShr:
BBChanged |= processAShr(cast<BinaryOperator>(II), LVI);
break;
+ case Instruction::SExt:
+ BBChanged |= processSExt(cast<SExtInst>(II), LVI);
+ break;
case Instruction::Add:
case Instruction::Sub:
BBChanged |= processBinOp(cast<BinaryOperator>(II), LVI);
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -1
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[EXT_WIDE:%.*]] = sext i32 [[A]] to i64
-; CHECK-NEXT: call void @use64(i64 [[EXT_WIDE]])
-; CHECK-NEXT: [[EXT]] = trunc i64 [[EXT_WIDE]] to i32
+; CHECK-NEXT: [[EXT_WIDE1:%.*]] = zext i32 [[A]] to i64
+; CHECK-NEXT: call void @use64(i64 [[EXT_WIDE1]])
+; CHECK-NEXT: [[EXT]] = trunc i64 [[EXT_WIDE1]] to i32
; CHECK-NEXT: br label [[FOR_COND]]
; CHECK: for.end:
; CHECK-NEXT: ret void
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
-; CHECK-NEXT: [[EXT_WIDE:%.*]] = sext i32 [[N]] to i64
-; CHECK-NEXT: call void @use64(i64 [[EXT_WIDE]])
-; CHECK-NEXT: [[EXT:%.*]] = trunc i64 [[EXT_WIDE]] to i32
+; CHECK-NEXT: [[EXT_WIDE1:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT: call void @use64(i64 [[EXT_WIDE1]])
+; CHECK-NEXT: [[EXT:%.*]] = trunc i64 [[EXT_WIDE1]] to i32
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void