[llvm] d8b2232 - [InstCombine] Fold fpto{u, s}i of int-cast fdiv into {u,s}div (#205853)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 5 09:58:33 PDT 2026
Author: Sungbin Jo
Date: 2026-07-06T00:58:28+08:00
New Revision: d8b223292490e9abdbce87278044de406e0242f3
URL: https://github.com/llvm/llvm-project/commit/d8b223292490e9abdbce87278044de406e0242f3
DIFF: https://github.com/llvm/llvm-project/commit/d8b223292490e9abdbce87278044de406e0242f3.diff
LOG: [InstCombine] Fold fpto{u,s}i of int-cast fdiv into {u,s}div (#205853)
Fixes #205305.
Adds an InstCombine fold for the pattern `fpto{u,s}i (fdiv ({u,s}itofp
X), C)` to `{u,s}div X, C`.
Safe when
- Unsigned: C > 0 and the integer width N <= the FP mantissa width p.
- Signed: C != 0 and N - 1 <= p, excluding (X == INT_MIN, C == -1).
See linked issue for detailed reasoning.
Added:
llvm/test/Transforms/InstCombine/fptoui-of-fdiv.ll
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index d5ca48b7d0ecb..37ef4e6736d34 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2511,7 +2511,64 @@ static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) {
if (FPClass.isKnownNever(Mask))
return IC.replaceInstUsesWith(FI, ConstantInt::getNullValue(FI.getType()));
- return nullptr;
+ // fpto{u/s}i (fdiv ({u/s}itofp X to F), C_fp) --> {u/s}div X, C
+ //
+ // F has precision p (significand bits incl. hidden bit); C_fp is the exact FP
+ // value of the integer constant C. Given N = integer width, this is safe if:
+ // Unsigned: C > 0 and N <= p.
+ // Signed: C != 0 and N - 1 <= p, excluding (X == INT_MIN, C == -1) since
+ // sdiv INT_MIN, -1 is UB while the FP path only yields poison.
+ // fdiv X, -1 gets transformed to fneg in InstCombine regardless.
+ //
+ // The bounds make {u/s}itofp and C_fp exact (every |int| <= 2^p is exact),
+ // and ensure the rounded quotient never crosses an integer boundary:
+ // Rounding lemma: for 0 <= A <= 2^p, 1 <= B <= 2^p, q = floor(A/B),
+ // trunc(R_p(A/B)) = q.
+ // For r = A - qB > 0, m = q+1, half-gap H(m) <= q/2^p and
+ // m - A/B = (B-r)/B >= 1/B > q/2^p >= H(m), so R_p(A/B) < m; q = 0 is
+ // similar (H(1) = 2^(-p-1) < 2^-p <= 1/B).
+ // Signed case: by symmetry R_p(-z) = -R_p(z), so fptosi yields s*q = sdiv.
+ bool IsSigned = FI.getOpcode() == Instruction::FPToSI;
+ Value *X;
+ const APFloat *APF;
+ if (IsSigned) {
+ if (!match(FI.getOperand(0),
+ m_OneUse(m_FDiv(m_SIToFP(m_Value(X)), m_APFloat(APF)))))
+ return nullptr;
+ } else {
+ if (!match(FI.getOperand(0),
+ m_OneUse(m_FDiv(m_UIToFP(m_Value(X)), m_APFloat(APF)))))
+ return nullptr;
+ }
+ Type *IntTy = X->getType();
+ if (FI.getType() != IntTy)
+ return nullptr;
+
+ unsigned IntWidth = IntTy->getScalarSizeInBits();
+ unsigned Precision = APFloat::semanticsPrecision(APF->getSemantics());
+ if (Precision + IsSigned < IntWidth)
+ return nullptr;
+
+ if (!APF->isInteger())
+ return nullptr;
+
+ APSInt Divisor(IntWidth, !IsSigned);
+ bool IsExact = false;
+ APF->convertToInteger(Divisor, APFloat::rmTowardZero, &IsExact);
+ if (!IsExact)
+ return nullptr;
+
+ if (Divisor.isZero())
+ return nullptr;
+
+ // sdiv INT_MIN, -1 is UB, not poison, so this isn't valid if X == INT_MIN.
+ // fdiv X, -1 gets transformed to fneg anyways, so we do not handle C == -1.
+ if (IsSigned && Divisor.isAllOnes())
+ return nullptr;
+
+ Constant *C = ConstantInt::get(IntTy, Divisor);
+ return IsSigned ? BinaryOperator::CreateSDiv(X, C)
+ : BinaryOperator::CreateUDiv(X, C);
}
Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) {
diff --git a/llvm/test/Transforms/InstCombine/fptoui-of-fdiv.ll b/llvm/test/Transforms/InstCombine/fptoui-of-fdiv.ll
new file mode 100644
index 0000000000000..180b5915c05b1
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fptoui-of-fdiv.ll
@@ -0,0 +1,395 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; fpto{u/s}i (fdiv ({u/s}itofp X), C) -> {u/s}div X, C
+; Unsigned: sound when C >= 1 and N <= p.
+; Signed: sound when C not in {0, -1} and N - 1 <= p.
+; (N = integer width, p = FP mantissa width.)
+
+define i32 @i32_double_const(i32 %x) {
+; CHECK-LABEL: define i32 @i32_double_const(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = udiv i32 [[X]], 7
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i16 @i16_float_const(i16 %x) {
+; CHECK-LABEL: define i16 @i16_float_const(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = udiv i16 [[X]], 3
+; CHECK-NEXT: ret i16 [[R]]
+;
+ %a = uitofp i16 %x to float
+ %d = fdiv float %a, 3.000000e+00
+ %r = fptoui float %d to i16
+ ret i16 %r
+}
+
+define <2 x i32> @vec_i32_double_const(<2 x i32> %x) {
+; CHECK-LABEL: define <2 x i32> @vec_i32_double_const(
+; CHECK-SAME: <2 x i32> [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = udiv <2 x i32> [[X]], splat (i32 7)
+; CHECK-NEXT: ret <2 x i32> [[R]]
+;
+ %a = uitofp <2 x i32> %x to <2 x double>
+ %d = fdiv <2 x double> %a, splat (double 7.000000e+00)
+ %r = fptoui <2 x double> %d to <2 x i32>
+ ret <2 x i32> %r
+}
+
+define <4 x i16> @vec_i16_float_neg_divisor(<4 x i16> %x) {
+; CHECK-LABEL: define <4 x i16> @vec_i16_float_neg_divisor(
+; CHECK-SAME: <4 x i16> [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = sdiv <4 x i16> [[X]], splat (i16 -3)
+; CHECK-NEXT: ret <4 x i16> [[R]]
+;
+ %a = sitofp <4 x i16> %x to <4 x float>
+ %d = fdiv <4 x float> %a, splat (float -3.000000e+00)
+ %r = fptosi <4 x float> %d to <4 x i16>
+ ret <4 x i16> %r
+}
+
+define i32 @divisor_one(i32 %x) {
+; CHECK-LABEL: define i32 @divisor_one(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: ret i32 [[X]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 1.000000e+00
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i64 @i64_double_not_exact(i64 %x) {
+; CHECK-LABEL: define i64 @i64_double_not_exact(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i64 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i64
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %a = uitofp i64 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptoui double %d to i64
+ ret i64 %r
+}
+
+define i32 @i32_float_not_exact(i32 %x) {
+; CHECK-LABEL: define i32 @i32_float_not_exact(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to float
+; CHECK-NEXT: [[D:%.*]] = fdiv float [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui float [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to float
+ %d = fdiv float %a, 7.000000e+00
+ %r = fptoui float %d to i32
+ ret i32 %r
+}
+
+define i32 @fractional_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @fractional_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 2.500000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 2.500000e+00
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i32 @zero_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @zero_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 0.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 0.000000e+00
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i64 @width_mismatch(i32 %x) {
+; CHECK-LABEL: define i64 @width_mismatch(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i64
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptoui double %d to i64
+ ret i64 %r
+}
+
+define i32 @variable_divisor(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @variable_divisor(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT: [[B:%.*]] = uitofp i32 [[Y]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], [[B]]
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %b = uitofp i32 %y to double
+ %d = fdiv double %a, %b
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i32 @signed_source(i32 %x) {
+; CHECK-LABEL: define i32 @signed_source(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i32 @overflow_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @overflow_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], f0x4202A05F1FF80000
+; CHECK-NEXT: [[R:%.*]] = fptoui double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 9999999999.0
+ %r = fptoui double %d to i32
+ ret i32 %r
+}
+
+define i128 @ppc_fp128_unknown_precision(i128 %x) {
+; CHECK-LABEL: define i128 @ppc_fp128_unknown_precision(
+; CHECK-SAME: i128 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i128 [[X]] to ppc_fp128
+; CHECK-NEXT: [[D:%.*]] = fdiv ppc_fp128 [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui ppc_fp128 [[D]] to i128
+; CHECK-NEXT: ret i128 [[R]]
+;
+ %a = uitofp i128 %x to ppc_fp128
+ %d = fdiv ppc_fp128 %a, 7.000000e+00
+ %r = fptoui ppc_fp128 %d to i128
+ ret i128 %r
+}
+
+; Unsound when N(=32) > p(=24) even if %x canBeCastedExactlyIntToFP (%x mod 256 = 0).
+define i32 @unsound_i32_float_shifted(i24 %a) {
+; CHECK-LABEL: define i32 @unsound_i32_float_shifted(
+; CHECK-SAME: i24 [[A:%.*]]) {
+; CHECK-NEXT: [[Z:%.*]] = zext i24 [[A]] to i32
+; CHECK-NEXT: [[X:%.*]] = shl nuw i32 [[Z]], 8
+; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[X]] to float
+; CHECK-NEXT: [[D:%.*]] = fdiv float [[F]], 3.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptoui float [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %z = zext i24 %a to i32
+ %x = shl i32 %z, 8
+ %f = uitofp i32 %x to float
+ %d = fdiv float %f, 3.000000e+00
+ %r = fptoui float %d to i32
+ ret i32 %r
+}
+
+define i32 @si32_double_const(i32 %x) {
+; CHECK-LABEL: define i32 @si32_double_const(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[X]], 7
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+define i32 @si32_double_neg_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @si32_double_neg_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[X]], -7
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, -7.000000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+define i16 @si16_float_const(i16 %x) {
+; CHECK-LABEL: define i16 @si16_float_const(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = sdiv i16 [[X]], 3
+; CHECK-NEXT: ret i16 [[R]]
+;
+ %a = sitofp i16 %x to float
+ %d = fdiv float %a, 3.000000e+00
+ %r = fptosi float %d to i16
+ ret i16 %r
+}
+
+define i24 @si24_float_const(i24 %x) {
+; CHECK-LABEL: define i24 @si24_float_const(
+; CHECK-SAME: i24 [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = sdiv i24 [[X]], 3
+; CHECK-NEXT: ret i24 [[R]]
+;
+ %a = sitofp i24 %x to float
+ %d = fdiv float %a, 3.000000e+00
+ %r = fptosi float %d to i24
+ ret i24 %r
+}
+
+define <2 x i32> @si32_double_vec(<2 x i32> %x) {
+; CHECK-LABEL: define <2 x i32> @si32_double_vec(
+; CHECK-SAME: <2 x i32> [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = sdiv <2 x i32> [[X]], splat (i32 7)
+; CHECK-NEXT: ret <2 x i32> [[R]]
+;
+ %a = sitofp <2 x i32> %x to <2 x double>
+ %d = fdiv <2 x double> %a, splat (double 7.000000e+00)
+ %r = fptosi <2 x double> %d to <2 x i32>
+ ret <2 x i32> %r
+}
+
+define i32 @si32_divisor_one(i32 %x) {
+; CHECK-LABEL: define i32 @si32_divisor_one(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: ret i32 [[X]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 1.000000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+; Do not transform fptosi (fdiv (sitofp INT_MIN), -1) (poison) into sdiv INT_MIN, -1 (UB).
+; fdiv X, -1.0 is canonicalized to fneg before our transform runs.
+define i32 @si32_divisor_neg_one(i32 %x) {
+; CHECK-LABEL: define i32 @si32_divisor_neg_one(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fneg double [[A]]
+; CHECK-NEXT: [[R:%.*]] = fptosi double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, -1.000000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+define i64 @si64_double_not_exact(i64 %x) {
+; CHECK-LABEL: define i64 @si64_double_not_exact(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i64 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptosi double [[D]] to i64
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %a = sitofp i64 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptosi double %d to i64
+ ret i64 %r
+}
+
+define i32 @si32_float_not_exact(i32 %x) {
+; CHECK-LABEL: define i32 @si32_float_not_exact(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to float
+; CHECK-NEXT: [[D:%.*]] = fdiv float [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptosi float [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to float
+ %d = fdiv float %a, 7.000000e+00
+ %r = fptosi float %d to i32
+ ret i32 %r
+}
+
+define i32 @si32_fractional_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @si32_fractional_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 2.500000e+00
+; CHECK-NEXT: [[R:%.*]] = fptosi double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 2.500000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+define i32 @si32_zero_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @si32_zero_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: ret i32 0
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 0.000000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+define i64 @si32_width_mismatch(i32 %x) {
+; CHECK-LABEL: define i64 @si32_width_mismatch(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptosi double [[D]] to i64
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptosi double %d to i64
+ ret i64 %r
+}
+
+define i32 @si32_unsigned_source(i32 %x) {
+; CHECK-LABEL: define i32 @si32_unsigned_source(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], 7.000000e+00
+; CHECK-NEXT: [[R:%.*]] = fptosi double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = uitofp i32 %x to double
+ %d = fdiv double %a, 7.000000e+00
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
+
+define i32 @si32_overflow_divisor(i32 %x) {
+; CHECK-LABEL: define i32 @si32_overflow_divisor(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to double
+; CHECK-NEXT: [[D:%.*]] = fdiv double [[A]], f0x4202A05F1FF80000
+; CHECK-NEXT: [[R:%.*]] = fptosi double [[D]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %a = sitofp i32 %x to double
+ %d = fdiv double %a, 9999999999.0
+ %r = fptosi double %d to i32
+ ret i32 %r
+}
More information about the llvm-commits
mailing list