Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false);
return InsertValueInst::Create(Struct, II->getArgOperand(0), 0);
}
+
+ // [su]mul.with.overflow(X, 2) -> [su]add.with.overflow(X, X)
+ if (RHSI->equalsInt(2)) {
+ Intrinsic::ID Add =
+ II->getIntrinsicID() == Intrinsic::smul_with_overflow ?
+ Intrinsic::sadd_with_overflow : Intrinsic::uadd_with_overflow;
+
+ Module *M = II->getParent()->getParent()->getParent();
+ const Type *Ty = RHSI->getType();
+ Function *F = Intrinsic::getDeclaration(M, Add, &Ty, 1);
+
+ Value *Ops[] = { II->getArgOperand(0), II->getArgOperand(0) };
+ return CallInst::Create(F, Ops, Ops+2);
+ }
}
break;
case Intrinsic::ppc_altivec_lvx:
%ov.result.32 = type { i32, i1 }
declare %ov.result.32 @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
+declare %ov.result.32 @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
define i32 @umultest3(i32 %n) nounwind {
%shr = lshr i32 %n, 2
; CHECK: umul.with.overflow
}
+define i32 @umultest5(i32 %n) nounwind {
+ %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %n, i32 2)
+ %ov = extractvalue %ov.result.32 %mul, 1
+ %res = extractvalue %ov.result.32 %mul, 0
+ %ret = select i1 %ov, i32 -1, i32 %res
+ ret i32 %ret
+; CHECK: @umultest5
+; CHECK: llvm.uadd.with.overflow.i32(i32 %n, i32 %n)
+}
+
+define i32 @smultest1(i32 %n) nounwind {
+ %mul = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %n, i32 2)
+ %ov = extractvalue %ov.result.32 %mul, 1
+ %res = extractvalue %ov.result.32 %mul, 0
+ %ret = select i1 %ov, i32 -1, i32 %res
+ ret i32 %ret
+; CHECK: @smultest1
+; CHECK: llvm.sadd.with.overflow.i32(i32 %n, i32 %n)
+}
+
define void @powi(double %V, double *%P) {
entry:
%A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind