[clang] [llvm] [InstCombine][CVP][SCCP] Add support for `uitofp nneg` (PR #86154)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 9 21:25:21 PDT 2024
https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/86154
>From ea9f3393a46f421c3ba96f924f302c5ac4b3e3b0 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 21 Mar 2024 11:01:21 -0500
Subject: [PATCH 1/4] [InstCombine] Add canonicalization of `sitofp` -> `uitofp
nneg`
This is essentially the same as #82404 but has the `nneg` flag which
allows the backend to reliably undo the transform.
---
clang/test/Headers/__clang_hip_math.hip | 24 +++----
.../InstCombine/InstCombineCasts.cpp | 18 ++++-
.../test/Transforms/InstCombine/add-sitofp.ll | 20 +++---
.../Transforms/InstCombine/binop-itofp.ll | 66 +++++++++----------
.../Transforms/InstCombine/clamp-to-minmax.ll | 10 +--
llvm/test/Transforms/InstCombine/fpcast.ll | 24 +++----
.../Transforms/InstCombine/minmax-fold.ll | 10 +--
llvm/test/Transforms/InstCombine/minmax-fp.ll | 2 +-
llvm/test/Transforms/InstCombine/pr27236.ll | 2 +-
llvm/test/Transforms/InstCombine/sitofp.ll | 2 +-
.../LoopVectorize/X86/float-induction-x86.ll | 6 +-
.../LoopVectorize/float-induction.ll | 56 ++++++++--------
12 files changed, 127 insertions(+), 113 deletions(-)
diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip
index 37099de74fb8ec..bff1708120604b 100644
--- a/clang/test/Headers/__clang_hip_math.hip
+++ b/clang/test/Headers/__clang_hip_math.hip
@@ -1685,7 +1685,7 @@ extern "C" __device__ double test_j1(double x) {
// DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float
+// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to float
// DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]]
// DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]]
// DEFAULT-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]]
@@ -1718,7 +1718,7 @@ extern "C" __device__ double test_j1(double x) {
// FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float
+// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to float
// FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract float [[CONV_I]], [[Y]]
// FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract float [[__X1_0_I3]], [[DIV_I]]
// FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract float [[MUL8_I]], [[__X0_0_I2]]
@@ -1751,7 +1751,7 @@ extern "C" __device__ double test_j1(double x) {
// APPROX-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float
+// APPROX-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to float
// APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]]
// APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]]
// APPROX-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]]
@@ -1788,7 +1788,7 @@ extern "C" __device__ float test_jnf(int x, float y) {
// DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double
+// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to double
// DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]]
// DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]]
// DEFAULT-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]]
@@ -1821,7 +1821,7 @@ extern "C" __device__ float test_jnf(int x, float y) {
// FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double
+// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to double
// FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract double [[CONV_I]], [[Y]]
// FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract double [[__X1_0_I3]], [[DIV_I]]
// FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract double [[MUL8_I]], [[__X0_0_I2]]
@@ -1854,7 +1854,7 @@ extern "C" __device__ float test_jnf(int x, float y) {
// APPROX-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double
+// APPROX-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to double
// APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]]
// APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]]
// APPROX-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]]
@@ -4222,7 +4222,7 @@ extern "C" __device__ double test_y1(double x) {
// DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float
+// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to float
// DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]]
// DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]]
// DEFAULT-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]]
@@ -4255,7 +4255,7 @@ extern "C" __device__ double test_y1(double x) {
// FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float
+// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to float
// FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract float [[CONV_I]], [[Y]]
// FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract float [[__X1_0_I3]], [[DIV_I]]
// FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract float [[MUL8_I]], [[__X0_0_I2]]
@@ -4288,7 +4288,7 @@ extern "C" __device__ double test_y1(double x) {
// APPROX-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float
+// APPROX-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to float
// APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]]
// APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]]
// APPROX-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]]
@@ -4325,7 +4325,7 @@ extern "C" __device__ float test_ynf(int x, float y) {
// DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double
+// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to double
// DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]]
// DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]]
// DEFAULT-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]]
@@ -4358,7 +4358,7 @@ extern "C" __device__ float test_ynf(int x, float y) {
// FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double
+// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to double
// FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract double [[CONV_I]], [[Y]]
// FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract double [[__X1_0_I3]], [[DIV_I]]
// FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract double [[MUL8_I]], [[__X0_0_I2]]
@@ -4391,7 +4391,7 @@ extern "C" __device__ float test_ynf(int x, float y) {
// APPROX-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ]
// APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1
-// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double
+// APPROX-NEXT: [[CONV_I:%.*]] = uitofp nneg i32 [[MUL_I]] to double
// APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]]
// APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]]
// APPROX-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]]
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 0652a8ba80b3fe..0a95a9224db025 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1964,11 +1964,25 @@ Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) {
}
Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) {
- return commonCastTransforms(CI);
+ if (Instruction *R = commonCastTransforms(CI))
+ return R;
+ if (!CI.hasNonNeg() && isKnownNonNegative(CI.getOperand(0), SQ)) {
+ CI.setNonNeg();
+ return &CI;
+ }
+ return nullptr;
}
Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) {
- return commonCastTransforms(CI);
+ if (Instruction *R = commonCastTransforms(CI))
+ return R;
+ if (isKnownNonNegative(CI.getOperand(0), SQ)) {
+ auto UI =
+ CastInst::Create(Instruction::UIToFP, CI.getOperand(0), CI.getType());
+ UI->setNonNeg(true);
+ return UI;
+ }
+ return nullptr;
}
Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
diff --git a/llvm/test/Transforms/InstCombine/add-sitofp.ll b/llvm/test/Transforms/InstCombine/add-sitofp.ll
index 2bdc808d9771c4..f1afcaf5f85d2a 100644
--- a/llvm/test/Transforms/InstCombine/add-sitofp.ll
+++ b/llvm/test/Transforms/InstCombine/add-sitofp.ll
@@ -6,7 +6,7 @@ define double @x(i32 %a, i32 %b) {
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
-; CHECK-NEXT: [[P:%.*]] = uitofp i32 [[TMP1]] to double
+; CHECK-NEXT: [[P:%.*]] = uitofp nneg i32 [[TMP1]] to double
; CHECK-NEXT: ret double [[P]]
;
%m = lshr i32 %a, 24
@@ -20,7 +20,7 @@ define double @test(i32 %a) {
; CHECK-LABEL: @test(
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], 1
-; CHECK-NEXT: [[RES:%.*]] = uitofp i32 [[TMP1]] to double
+; CHECK-NEXT: [[RES:%.*]] = uitofp nneg i32 [[TMP1]] to double
; CHECK-NEXT: ret double [[RES]]
;
; Drop two highest bits to guarantee that %a + 1 doesn't overflow
@@ -33,7 +33,7 @@ define double @test(i32 %a) {
define float @test_neg(i32 %a) {
; CHECK-LABEL: @test_neg(
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
-; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
+; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp nneg i32 [[A_AND]] to float
; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], 1.000000e+00
; CHECK-NEXT: ret float [[RES]]
;
@@ -49,7 +49,7 @@ define double @test_2(i32 %a, i32 %b) {
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
-; CHECK-NEXT: [[RES:%.*]] = uitofp i32 [[TMP1]] to double
+; CHECK-NEXT: [[RES:%.*]] = uitofp nneg i32 [[TMP1]] to double
; CHECK-NEXT: ret double [[RES]]
;
; Drop two highest bits to guarantee that %a + %b doesn't overflow
@@ -67,8 +67,8 @@ define float @test_2_neg(i32 %a, i32 %b) {
; CHECK-LABEL: @test_2_neg(
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
-; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
-; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp i32 [[B_AND]] to float
+; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp nneg i32 [[A_AND]] to float
+; CHECK-NEXT: [[B_AND_FP:%.*]] = uitofp nneg i32 [[B_AND]] to float
; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], [[B_AND_FP]]
; CHECK-NEXT: ret float [[RES]]
;
@@ -89,7 +89,7 @@ define float @test_3(i32 %a, i32 %b) {
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
-; CHECK-NEXT: [[P:%.*]] = uitofp i32 [[TMP1]] to float
+; CHECK-NEXT: [[P:%.*]] = uitofp nneg i32 [[TMP1]] to float
; CHECK-NEXT: ret float [[P]]
;
%m = lshr i32 %a, 24
@@ -104,7 +104,7 @@ define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
-; CHECK-NEXT: [[RES:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x double>
+; CHECK-NEXT: [[RES:%.*]] = uitofp nneg <4 x i32> [[TMP1]] to <4 x double>
; CHECK-NEXT: ret <4 x double> [[RES]]
;
; Drop two highest bits to guarantee that %a + %b doesn't overflow
@@ -122,8 +122,8 @@ define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @test_4_neg(
; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
-; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp <4 x i32> [[A_AND]] to <4 x float>
-; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp <4 x i32> [[B_AND]] to <4 x float>
+; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp nneg <4 x i32> [[A_AND]] to <4 x float>
+; CHECK-NEXT: [[B_AND_FP:%.*]] = uitofp nneg <4 x i32> [[B_AND]] to <4 x float>
; CHECK-NEXT: [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]]
; CHECK-NEXT: ret <4 x float> [[RES]]
;
diff --git a/llvm/test/Transforms/InstCombine/binop-itofp.ll b/llvm/test/Transforms/InstCombine/binop-itofp.ll
index cd9ec1e59203ff..4f87b892e32a13 100644
--- a/llvm/test/Transforms/InstCombine/binop-itofp.ll
+++ b/llvm/test/Transforms/InstCombine/binop-itofp.ll
@@ -21,7 +21,7 @@ define half @test_ui_ui_i8_add_fail_overflow(i8 noundef %x_in, i8 noundef %y_in)
; CHECK-LABEL: @test_ui_ui_i8_add_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], -127
-; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -49,7 +49,7 @@ define half @test_ui_ui_i8_add_C(i8 noundef %x_in) {
define half @test_ui_ui_i8_add_C_fail_no_repr(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_add_C_fail_no_repr(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
-; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH57F8
; CHECK-NEXT: ret half [[R]]
;
@@ -62,7 +62,7 @@ define half @test_ui_ui_i8_add_C_fail_no_repr(i8 noundef %x_in) {
define half @test_ui_ui_i8_add_C_fail_overflow(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_add_C_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
-; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH5808
; CHECK-NEXT: ret half [[R]]
;
@@ -110,7 +110,7 @@ define half @test_ui_si_i8_add(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 63
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i8 %x_in, 63
@@ -140,7 +140,7 @@ define half @test_ui_si_i8_add_overflow(i8 noundef %x_in, i8 noundef %y_in) {
define half @test_ui_ui_i8_sub_C(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_sub_C(
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X_IN:%.*]], 127
-; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = or i8 %x_in, 128
@@ -166,7 +166,7 @@ define half @test_si_si_i8_sub(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -64
; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i8 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i8 %x_in, 63
@@ -181,7 +181,7 @@ define half @test_si_si_i8_sub_fail_overflow(i8 noundef %x_in, i8 noundef %y_in)
; CHECK-LABEL: @test_si_si_i8_sub_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -65
-; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -198,7 +198,7 @@ define half @test_si_si_i8_sub_C(i8 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i8_sub_C(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[X]], 64
-; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i8 %x_in, 63
@@ -283,7 +283,7 @@ define half @test_ui_ui_i8_mul_C(i8 noundef %x_in) {
define half @test_ui_ui_i8_mul_C_fail_overlow(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_mul_C_fail_overlow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 14
-; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xH4CC0
; CHECK-NEXT: ret half [[R]]
;
@@ -315,7 +315,7 @@ define half @test_si_si_i8_mul_fail_maybe_zero(i8 noundef %x_in, i8 noundef %y_i
; CHECK-LABEL: @test_si_si_i8_mul_fail_maybe_zero(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 7
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -8
-; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -332,7 +332,7 @@ define half @test_si_si_i8_mul_C_fail_no_repr(i8 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i8_mul_C_fail_no_repr(
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 6
; CHECK-NEXT: [[X:%.*]] = or disjoint i8 [[XX]], 1
-; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xHC780
; CHECK-NEXT: ret half [[R]]
;
@@ -347,7 +347,7 @@ define half @test_si_si_i8_mul_C_fail_overflow(i8 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i8_mul_C_fail_overflow(
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 6
; CHECK-NEXT: [[X:%.*]] = or disjoint i8 [[XX]], 1
-; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xHCCC0
; CHECK-NEXT: ret half [[R]]
;
@@ -365,7 +365,7 @@ define half @test_ui_si_i8_mul(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y_IN:%.*]], 7
; CHECK-NEXT: [[Y:%.*]] = add nuw nsw i8 [[YY]], 1
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i8 %x_in, 6
@@ -384,7 +384,7 @@ define half @test_ui_si_i8_mul_fail_maybe_zero(i8 noundef %x_in, i8 noundef %y_i
; CHECK-NEXT: [[X:%.*]] = add nuw nsw i8 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 7
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i8 %x_in, 7
@@ -401,7 +401,7 @@ define half @test_ui_si_i8_mul_fail_signed(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 7
; CHECK-NEXT: [[X:%.*]] = add nuw nsw i8 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -4
-; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -420,7 +420,7 @@ define half @test_ui_ui_i16_add(i16 noundef %x_in, i16 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i16 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i16 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i16 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i16 %x_in, 2047
@@ -435,8 +435,8 @@ define half @test_ui_ui_i16_add_fail_not_promotable(i16 noundef %x_in, i16 nound
; CHECK-LABEL: @test_ui_ui_i16_add_fail_not_promotable(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2049
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047
-; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
-; CHECK-NEXT: [[YF:%.*]] = uitofp i16 [[Y]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
+; CHECK-NEXT: [[YF:%.*]] = uitofp nneg i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
;
@@ -463,7 +463,7 @@ define half @test_ui_ui_i16_add_C(i16 noundef %x_in) {
define half @test_ui_ui_i16_add_C_fail_overflow(i16 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i16_add_C_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047
-; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH7BD0
; CHECK-NEXT: ret half [[R]]
;
@@ -541,7 +541,7 @@ define half @test_si_si_i16_sub_fail_no_promotion(i16 noundef %x_in, i16 noundef
; CHECK-LABEL: @test_si_si_i16_sub_fail_no_promotion(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y_IN:%.*]], -2049
-; CHECK-NEXT: [[XF:%.*]] = sitofp i16 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -575,7 +575,7 @@ define half @test_ui_si_i16_sub_fail_maybe_signed(i16 noundef %x_in, i16 noundef
; CHECK-NEXT: [[X:%.*]] = or i16 [[X_IN:%.*]], -2048
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047
; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
-; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half
+; CHECK-NEXT: [[YF:%.*]] = uitofp nneg i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
;
@@ -607,8 +607,8 @@ define half @test_ui_ui_i16_mul_fail_no_promotion(i16 noundef %x_in, i16 noundef
; CHECK-LABEL: @test_ui_ui_i16_mul_fail_no_promotion(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 4095
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 3
-; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
-; CHECK-NEXT: [[YF:%.*]] = uitofp i16 [[Y]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
+; CHECK-NEXT: [[YF:%.*]] = uitofp nneg i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
;
@@ -643,7 +643,7 @@ define half @test_si_si_i16_mul_fail_overflow(i16 noundef %x_in, i16 noundef %y_
; CHECK-NEXT: [[XX:%.*]] = and i16 [[X_IN:%.*]], 126
; CHECK-NEXT: [[X:%.*]] = or disjoint i16 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y_IN:%.*]], -257
-; CHECK-NEXT: [[XF:%.*]] = sitofp i16 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -690,7 +690,7 @@ define half @test_ui_si_i16_mul(i16 noundef %x_in, i16 noundef %y_in) {
; CHECK-NEXT: [[YY:%.*]] = and i16 [[Y_IN:%.*]], 126
; CHECK-NEXT: [[Y:%.*]] = or disjoint i16 [[YY]], 1
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i16 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i16 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i16 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i16 %x_in, 126
@@ -723,7 +723,7 @@ define half @test_ui_ui_i12_add_fail_overflow(i12 noundef %x_in, i12 noundef %y_
; CHECK-LABEL: @test_ui_ui_i12_add_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[Y:%.*]] = and i12 [[Y_IN:%.*]], -2047
-; CHECK-NEXT: [[XF:%.*]] = uitofp i12 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i12 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i12 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -821,7 +821,7 @@ define half @test_si_si_i12_sub(i12 noundef %x_in, i12 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 1023
; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -1024
; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i12 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i12 %x_in, 1023
@@ -850,7 +850,7 @@ define half @test_ui_ui_i12_mul(i12 noundef %x_in, i12 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 31
; CHECK-NEXT: [[Y:%.*]] = and i12 [[Y_IN:%.*]], 63
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i12 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i12 %x_in, 31
@@ -883,7 +883,7 @@ define half @test_ui_ui_i12_mul_C(i12 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i12_mul_C(
; CHECK-NEXT: [[X:%.*]] = shl i12 [[X_IN:%.*]], 6
; CHECK-NEXT: [[TMP1:%.*]] = and i12 [[X]], 1984
-; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i12 %x_in, 31
@@ -915,7 +915,7 @@ define half @test_si_si_i12_mul_fail_overflow(i12 noundef %x_in, i12 noundef %y_
; CHECK-NEXT: [[XX:%.*]] = and i12 [[X_IN:%.*]], 30
; CHECK-NEXT: [[X:%.*]] = or disjoint i12 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -128
-; CHECK-NEXT: [[XF:%.*]] = sitofp i12 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i12 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i12 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -933,7 +933,7 @@ define half @test_si_si_i12_mul_fail_maybe_non_zero(i12 noundef %x_in, i12 nound
; CHECK-LABEL: @test_si_si_i12_mul_fail_maybe_non_zero(
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 30
; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -128
-; CHECK-NEXT: [[XF:%.*]] = sitofp i12 [[X]] to half
+; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i12 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i12 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
@@ -950,7 +950,7 @@ define half @test_si_si_i12_mul_C(i12 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i12_mul_C(
; CHECK-NEXT: [[X:%.*]] = or i12 [[X_IN:%.*]], -64
; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i12 [[X]], -16
-; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = or i12 %x_in, -64
@@ -979,7 +979,7 @@ define half @test_ui_si_i12_mul_nsw(i12 noundef %x_in, i12 noundef %y_in) {
; CHECK-NEXT: [[YY:%.*]] = and i12 [[Y_IN:%.*]], 30
; CHECK-NEXT: [[Y:%.*]] = or disjoint i12 [[YY]], 1
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i12 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i12 %x_in, 31
diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
index 9da9eb36d381f0..1dd0b17e9f46dd 100644
--- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
+++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
@@ -472,7 +472,7 @@ define float @ui32_clamp_and_cast_to_float(i32 %x) {
; CHECK-LABEL: @ui32_clamp_and_cast_to_float(
; CHECK-NEXT: [[LO_CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
; CHECK-NEXT: [[MIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 255)
-; CHECK-NEXT: [[MIN:%.*]] = uitofp i32 [[MIN1]] to float
+; CHECK-NEXT: [[MIN:%.*]] = uitofp nneg i32 [[MIN1]] to float
; CHECK-NEXT: [[R:%.*]] = select i1 [[LO_CMP]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
;
@@ -488,7 +488,7 @@ define float @ui64_clamp_and_cast_to_float(i64 %x) {
; CHECK-LABEL: @ui64_clamp_and_cast_to_float(
; CHECK-NEXT: [[LO_CMP:%.*]] = icmp eq i64 [[X:%.*]], 0
; CHECK-NEXT: [[MIN1:%.*]] = call i64 @llvm.umin.i64(i64 [[X]], i64 255)
-; CHECK-NEXT: [[MIN:%.*]] = uitofp i64 [[MIN1]] to float
+; CHECK-NEXT: [[MIN:%.*]] = uitofp nneg i64 [[MIN1]] to float
; CHECK-NEXT: [[R:%.*]] = select i1 [[LO_CMP]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
;
@@ -504,7 +504,7 @@ define float @mixed_clamp_to_float_1(i32 %x) {
; CHECK-LABEL: @mixed_clamp_to_float_1(
; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1)
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%si_min_cmp = icmp sgt i32 %x, 255
@@ -539,7 +539,7 @@ define float @mixed_clamp_to_float_2(i32 %x) {
; CHECK-LABEL: @mixed_clamp_to_float_2(
; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1)
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%si_min_cmp = icmp sgt i32 %x, 255
@@ -572,7 +572,7 @@ define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) {
; CHECK-LABEL: @mixed_clamp_to_float_vec(
; CHECK-NEXT: [[SI_MIN:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 255>)
; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN]], <2 x i32> <i32 1, i32 1>)
-; CHECK-NEXT: [[R:%.*]] = sitofp <2 x i32> [[R1]] to <2 x float>
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg <2 x i32> [[R1]] to <2 x float>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%si_min_cmp = icmp sgt <2 x i32> %x, <i32 255, i32 255>
diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll
index ac4b88fcddd7ec..d2c932ba447e4e 100644
--- a/llvm/test/Transforms/InstCombine/fpcast.ll
+++ b/llvm/test/Transforms/InstCombine/fpcast.ll
@@ -170,7 +170,7 @@ define half @sint_to_fptrunc(i32 %x) {
define half @masked_sint_to_fptrunc1(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fptrunc1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = and i32 %x, 16777215
@@ -182,7 +182,7 @@ define half @masked_sint_to_fptrunc1(i32 %x) {
define half @masked_sint_to_fptrunc2(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fptrunc2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = lshr i32 %x, 8
@@ -194,7 +194,7 @@ define half @masked_sint_to_fptrunc2(i32 %x) {
define half @masked_sint_to_fptrunc3(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fptrunc3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
-; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[M]] to float
+; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half
; CHECK-NEXT: ret half [[R]]
;
@@ -218,7 +218,7 @@ define double @sint_to_fpext(i32 %x) {
define double @masked_sint_to_fpext1(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fpext1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to double
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = and i32 %x, 16777215
@@ -230,7 +230,7 @@ define double @masked_sint_to_fpext1(i32 %x) {
define double @masked_sint_to_fpext2(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fpext2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to double
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = lshr i32 %x, 8
@@ -242,7 +242,7 @@ define double @masked_sint_to_fpext2(i32 %x) {
define double @masked_sint_to_fpext3(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fpext3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
-; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[M]] to float
+; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double
; CHECK-NEXT: ret double [[R]]
;
@@ -266,7 +266,7 @@ define half @uint_to_fptrunc(i32 %x) {
define half @masked_uint_to_fptrunc1(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fptrunc1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
-; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = and i32 %x, 16777215
@@ -278,7 +278,7 @@ define half @masked_uint_to_fptrunc1(i32 %x) {
define half @masked_uint_to_fptrunc2(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fptrunc2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
-; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to half
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = lshr i32 %x, 8
@@ -290,7 +290,7 @@ define half @masked_uint_to_fptrunc2(i32 %x) {
define half @masked_uint_to_fptrunc3(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fptrunc3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[M]] to float
+; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half
; CHECK-NEXT: ret half [[R]]
;
@@ -314,7 +314,7 @@ define double @uint_to_fpext(i32 %x) {
define double @masked_uint_to_fpext1(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fpext1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
-; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to double
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = and i32 %x, 16777215
@@ -326,7 +326,7 @@ define double @masked_uint_to_fpext1(i32 %x) {
define double @masked_uint_to_fpext2(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fpext2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
-; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to double
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = lshr i32 %x, 8
@@ -338,7 +338,7 @@ define double @masked_uint_to_fpext2(i32 %x) {
define double @masked_uint_to_fpext3(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fpext3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[M]] to float
+; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double
; CHECK-NEXT: ret double [[R]]
;
diff --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll
index 8391fe33eb9b59..bbbbf9eb6eafe4 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fold.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll
@@ -131,7 +131,7 @@ define i64 @t9(i32 %a) {
define float @t10(i32 %x) {
; CHECK-LABEL: @t10(
; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%f_x = sitofp i32 %x to float
@@ -143,7 +143,7 @@ define float @t10(i32 %x) {
define float @t11(i64 %x) {
; CHECK-LABEL: @t11(
; CHECK-NEXT: [[R1:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 255)
-; CHECK-NEXT: [[R:%.*]] = sitofp i64 [[R1]] to float
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i64 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%f_x = sitofp i64 %x to float
@@ -526,7 +526,7 @@ falselabel:
define double @PR31751_umin1(i32 %x) {
; CHECK-LABEL: @PR31751_umin1(
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
-; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double
+; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double
; CHECK-NEXT: ret double [[CONV]]
;
%cmp = icmp slt i32 %x, 0
@@ -538,7 +538,7 @@ define double @PR31751_umin1(i32 %x) {
define double @PR31751_umin2(i32 %x) {
; CHECK-LABEL: @PR31751_umin2(
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
-; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double
+; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double
; CHECK-NEXT: ret double [[CONV]]
;
%cmp = icmp ult i32 %x, 2147483647
@@ -550,7 +550,7 @@ define double @PR31751_umin2(i32 %x) {
define double @PR31751_umin3(i32 %x) {
; CHECK-LABEL: @PR31751_umin3(
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
-; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double
+; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double
; CHECK-NEXT: ret double [[CONV]]
;
%cmp = icmp ugt i32 %x, 2147483647
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index f89e8a18e63440..b9e46caa63753a 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -257,7 +257,7 @@ define double @t16(i32 %x) {
define double @t17(i32 %x) {
; CHECK-LABEL: @t17(
; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 2)
-; CHECK-NEXT: [[SEL:%.*]] = sitofp i32 [[SEL1]] to double
+; CHECK-NEXT: [[SEL:%.*]] = uitofp nneg i32 [[SEL1]] to double
; CHECK-NEXT: ret double [[SEL]]
;
%cmp = icmp sgt i32 %x, 2
diff --git a/llvm/test/Transforms/InstCombine/pr27236.ll b/llvm/test/Transforms/InstCombine/pr27236.ll
index 61ea344b1bdbd4..67c320d3524664 100644
--- a/llvm/test/Transforms/InstCombine/pr27236.ll
+++ b/llvm/test/Transforms/InstCombine/pr27236.ll
@@ -4,7 +4,7 @@
define float @test1(i32 %scale) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[SCALE:%.*]], i32 1)
-; CHECK-NEXT: [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float
+; CHECK-NEXT: [[TMP2:%.*]] = uitofp nneg i32 [[TMP1]] to float
; CHECK-NEXT: ret float [[TMP2]]
;
%1 = icmp sgt i32 1, %scale
diff --git a/llvm/test/Transforms/InstCombine/sitofp.ll b/llvm/test/Transforms/InstCombine/sitofp.ll
index cc6b6425eb03c8..51eff39cd900e2 100644
--- a/llvm/test/Transforms/InstCombine/sitofp.ll
+++ b/llvm/test/Transforms/InstCombine/sitofp.ll
@@ -256,7 +256,7 @@ define i25 @consider_lowbits_masked_input(i25 %A) {
define i32 @overflow_masked_input(i32 %A) {
; CHECK-LABEL: @overflow_masked_input(
; CHECK-NEXT: [[M:%.*]] = and i32 [[A:%.*]], 16777217
-; CHECK-NEXT: [[B:%.*]] = uitofp i32 [[M]] to float
+; CHECK-NEXT: [[B:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32
; CHECK-NEXT: ret i32 [[C]]
;
diff --git a/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll b/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
index c55e732c901475..59b8ce42380d9d 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
@@ -25,7 +25,7 @@ define void @fp_iv_loop1(ptr noalias nocapture %A, i32 %N) #0 {
; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; AUTO_VEC: vector.ph:
; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[ZEXT]], 2147483616
-; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; AUTO_VEC-NEXT: [[TMP0:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; AUTO_VEC-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP0]], 1.000000e+00
; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -201,7 +201,7 @@ define double @external_use_with_fast_math(ptr %a, i64 %n) {
; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; AUTO_VEC: vector.ph:
; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775792
-; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to double
+; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to double
; AUTO_VEC-NEXT: [[TMP0:%.*]] = fmul fast double [[DOTCAST]], 3.000000e+00
; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]]
; AUTO_VEC: vector.body:
@@ -366,7 +366,7 @@ define void @fadd_reassoc_FMF(ptr nocapture %p, i32 %N) {
; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; AUTO_VEC: vector.ph:
; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 4294967264
-; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; AUTO_VEC-NEXT: [[TMP1:%.*]] = fmul reassoc float [[DOTCAST]], 4.200000e+01
; AUTO_VEC-NEXT: [[IND_END:%.*]] = fadd reassoc float [[TMP1]], 1.000000e+00
; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]]
diff --git a/llvm/test/Transforms/LoopVectorize/float-induction.ll b/llvm/test/Transforms/LoopVectorize/float-induction.ll
index caea114e3d4487..bd658c31768a84 100644
--- a/llvm/test/Transforms/LoopVectorize/float-induction.ll
+++ b/llvm/test/Transforms/LoopVectorize/float-induction.ll
@@ -29,7 +29,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N)
; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL1: vector.ph:
; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644
-; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]]
; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]]
; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -84,7 +84,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N)
; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL2: vector.ph:
; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640
-; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]]
; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]]
; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -142,7 +142,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N)
; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC1_INTERL2: vector.ph:
; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]]
; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]]
; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -193,7 +193,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N)
; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.ph:
; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0
@@ -276,7 +276,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32
; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL1: vector.ph:
; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644
-; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]]
; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]]
; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -331,7 +331,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32
; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL2: vector.ph:
; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640
-; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]]
; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]]
; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -389,7 +389,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32
; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC1_INTERL2: vector.ph:
; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]]
; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]]
; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -442,7 +442,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32
; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.ph:
; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0
@@ -526,7 +526,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 {
; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL1: vector.ph:
; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644
-; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]]
; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -574,7 +574,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 {
; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL2: vector.ph:
; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640
-; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]]
; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -625,7 +625,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 {
; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC1_INTERL2: vector.ph:
; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]]
; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -675,7 +675,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 {
; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.ph:
; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0
@@ -758,10 +758,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca
; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL1: vector.ph:
; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483644
-; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01
; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000
-; VEC4_INTERL1-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST2:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]]
; VEC4_INTERL1-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]]
; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -835,10 +835,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca
; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL2: vector.ph:
; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483640
-; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01
; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000
-; VEC4_INTERL2-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST2:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]]
; VEC4_INTERL2-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]]
; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0
@@ -922,10 +922,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca
; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC1_INTERL2: vector.ph:
; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483646
-; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01
; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000
-; VEC1_INTERL2-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST2:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]]
; VEC1_INTERL2-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]]
; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -1000,10 +1000,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca
; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.ph:
; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483646
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01
; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST2:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]]
; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0
@@ -1113,7 +1113,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) {
; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL1: vector.ph:
; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644
-; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00
; VEC4_INTERL1-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -1158,7 +1158,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) {
; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL2: vector.ph:
; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640
-; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00
; VEC4_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -1206,7 +1206,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) {
; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC1_INTERL2: vector.ph:
; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00
; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -1256,7 +1256,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) {
; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.ph:
; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00
; VEC2_INTERL1_PRED_STORE-NEXT: br label [[VECTOR_BODY:%.*]]
@@ -1319,7 +1319,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) {
; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL1: vector.ph:
; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775804
-; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL1-NEXT: br label [[VECTOR_BODY:%.*]]
; VEC4_INTERL1: vector.body:
; VEC4_INTERL1-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE8:%.*]] ]
@@ -1396,7 +1396,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) {
; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC4_INTERL2: vector.ph:
; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775800
-; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC4_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
; VEC4_INTERL2: vector.body:
; VEC4_INTERL2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE17:%.*]] ]
@@ -1512,7 +1512,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) {
; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; VEC1_INTERL2: vector.ph:
; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775806
-; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]]
; VEC1_INTERL2: vector.body:
; VEC1_INTERL2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE4:%.*]] ]
@@ -1570,7 +1570,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) {
; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.ph:
; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775806
-; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
+; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; VEC2_INTERL1_PRED_STORE-NEXT: br label [[VECTOR_BODY:%.*]]
; VEC2_INTERL1_PRED_STORE: vector.body:
; VEC2_INTERL1_PRED_STORE-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE4:%.*]] ]
>From 927e3aacab6555986cb08aace9263fe6d932c9e8 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 21 Mar 2024 01:28:09 -0500
Subject: [PATCH 2/4] [CVP] Add tests for adding `nneg` flag to `uitofp` and
converting `sitofp` -> `uitofp nneg`; NFC
---
.../CorrelatedValuePropagation/sitofp.ll | 203 ++++++++++++++++++
.../CorrelatedValuePropagation/uitofp.ll | 203 ++++++++++++++++++
2 files changed, 406 insertions(+)
create mode 100644 llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll
create mode 100644 llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll
new file mode 100644
index 00000000000000..7a49a33fbf9e6c
--- /dev/null
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll
@@ -0,0 +1,203 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
+
+declare void @use.f32(float)
+
+define void @test1_fptosi(i32 %n) {
+; CHECK-LABEL: @test1_fptosi(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
+; 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:%.*]] = sitofp i32 [[A]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: [[EXT]] = fptosi float [[EXT_WIDE]] to i32
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
+ %cmp = icmp sgt i32 %a, -1
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %ext.wide = sitofp i32 %a to float
+ call void @use.f32(float %ext.wide)
+ %ext = fptosi float %ext.wide to i32
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+define void @test1_fptoui(i32 %n) {
+; CHECK-LABEL: @test1_fptoui(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
+; 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:%.*]] = sitofp i32 [[A]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: [[EXT]] = fptoui float [[EXT_WIDE]] to i32
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
+ %cmp = icmp sgt i32 %a, -1
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %ext.wide = sitofp i32 %a to float
+ call void @use.f32(float %ext.wide)
+ %ext = fptoui float %ext.wide to i32
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+;; Negative test to show transform doesn't happen unless n >= 0.
+define void @test2(i32 %n) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -2
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = sitofp i32 [[A]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: [[EXT]] = fptosi float [[EXT_WIDE]] to i32
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
+ %cmp = icmp sgt i32 %a, -2
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %ext.wide = sitofp i32 %a to float
+ call void @use.f32(float %ext.wide)
+ %ext = fptosi float %ext.wide to i32
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+;; Non looping test case.
+define void @test3(i32 %n) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
+; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
+; CHECK: bb:
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = sitofp i32 [[N]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp = icmp sgt i32 %n, -1
+ br i1 %cmp, label %bb, label %exit
+
+bb:
+ %ext.wide = sitofp i32 %n to float
+ call void @use.f32(float %ext.wide)
+ br label %exit
+
+exit:
+ ret void
+}
+
+;; Non looping negative test case.
+define void @test4(i32 %n) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -2
+; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
+; CHECK: bb:
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = sitofp i32 [[N]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp = icmp sgt i32 %n, -2
+ br i1 %cmp, label %bb, label %exit
+
+bb:
+ %ext.wide = sitofp i32 %n to float
+ call void @use.f32(float %ext.wide)
+ br label %exit
+
+exit:
+ ret void
+}
+
+define float @may_including_undef(i1 %c.1, i1 %c.2) {
+; CHECK-LABEL: @may_including_undef(
+; CHECK-NEXT: br i1 [[C_1:%.*]], label [[TRUE_1:%.*]], label [[FALSE:%.*]]
+; CHECK: true.1:
+; CHECK-NEXT: br i1 [[C_2:%.*]], label [[TRUE_2:%.*]], label [[EXIT:%.*]]
+; CHECK: true.2:
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: false:
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[TRUE_1]] ], [ 1, [[TRUE_2]] ], [ undef, [[FALSE]] ]
+; CHECK-NEXT: [[EXT:%.*]] = sitofp i32 [[P]] to float
+; CHECK-NEXT: ret float [[EXT]]
+;
+ br i1 %c.1, label %true.1, label %false
+
+true.1:
+ br i1 %c.2, label %true.2, label %exit
+
+true.2:
+ br label %exit
+
+false:
+ br label %exit
+
+exit:
+ %p = phi i32 [ 0, %true.1 ], [ 1, %true.2], [ undef, %false ]
+ %ext = sitofp i32 %p to float
+ ret float %ext
+}
+
+define double @test_infer_at_use(i32 noundef %n) {
+; CHECK-LABEL: @test_infer_at_use(
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
+; CHECK-NEXT: [[EXT:%.*]] = sitofp i32 [[N]] to double
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], double [[EXT]], double 0.000000e+00
+; CHECK-NEXT: ret double [[SELECT]]
+;
+ %cmp = icmp sgt i32 %n, -1
+ %ext = sitofp i32 %n to double
+ %select = select i1 %cmp, double %ext, double 0.0
+ ret double %select
+}
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll
new file mode 100644
index 00000000000000..1c9dc21c26feb7
--- /dev/null
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll
@@ -0,0 +1,203 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
+
+declare void @use.f32(float)
+
+define void @test1_fptosi(i32 %n) {
+; CHECK-LABEL: @test1_fptosi(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
+; 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:%.*]] = uitofp i32 [[A]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: [[EXT]] = fptosi float [[EXT_WIDE]] to i32
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
+ %cmp = icmp sgt i32 %a, -1
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %ext.wide = uitofp i32 %a to float
+ call void @use.f32(float %ext.wide)
+ %ext = fptosi float %ext.wide to i32
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+define void @test1_fptoui(i32 %n) {
+; CHECK-LABEL: @test1_fptoui(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
+; 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:%.*]] = uitofp i32 [[A]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: [[EXT]] = fptoui float [[EXT_WIDE]] to i32
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
+ %cmp = icmp sgt i32 %a, -1
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %ext.wide = uitofp i32 %a to float
+ call void @use.f32(float %ext.wide)
+ %ext = fptoui float %ext.wide to i32
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+;; Negative test to show transform doesn't happen unless n >= 0.
+define void @test2(i32 %n) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -2
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp i32 [[A]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: [[EXT]] = fptosi float [[EXT_WIDE]] to i32
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
+ %cmp = icmp sgt i32 %a, -2
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %ext.wide = uitofp i32 %a to float
+ call void @use.f32(float %ext.wide)
+ %ext = fptosi float %ext.wide to i32
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+;; Non looping test case.
+define void @test3(i32 %n) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
+; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
+; CHECK: bb:
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp i32 [[N]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp = icmp sgt i32 %n, -1
+ br i1 %cmp, label %bb, label %exit
+
+bb:
+ %ext.wide = uitofp i32 %n to float
+ call void @use.f32(float %ext.wide)
+ br label %exit
+
+exit:
+ ret void
+}
+
+;; Non looping negative test case.
+define void @test4(i32 %n) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -2
+; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
+; CHECK: bb:
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp i32 [[N]] to float
+; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp = icmp sgt i32 %n, -2
+ br i1 %cmp, label %bb, label %exit
+
+bb:
+ %ext.wide = uitofp i32 %n to float
+ call void @use.f32(float %ext.wide)
+ br label %exit
+
+exit:
+ ret void
+}
+
+define float @may_including_undef(i1 %c.1, i1 %c.2) {
+; CHECK-LABEL: @may_including_undef(
+; CHECK-NEXT: br i1 [[C_1:%.*]], label [[TRUE_1:%.*]], label [[FALSE:%.*]]
+; CHECK: true.1:
+; CHECK-NEXT: br i1 [[C_2:%.*]], label [[TRUE_2:%.*]], label [[EXIT:%.*]]
+; CHECK: true.2:
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: false:
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[TRUE_1]] ], [ 1, [[TRUE_2]] ], [ undef, [[FALSE]] ]
+; CHECK-NEXT: [[EXT:%.*]] = uitofp i32 [[P]] to float
+; CHECK-NEXT: ret float [[EXT]]
+;
+ br i1 %c.1, label %true.1, label %false
+
+true.1:
+ br i1 %c.2, label %true.2, label %exit
+
+true.2:
+ br label %exit
+
+false:
+ br label %exit
+
+exit:
+ %p = phi i32 [ 0, %true.1 ], [ 1, %true.2], [ undef, %false ]
+ %ext = uitofp i32 %p to float
+ ret float %ext
+}
+
+define double @test_infer_at_use(i32 noundef %n) {
+; CHECK-LABEL: @test_infer_at_use(
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
+; CHECK-NEXT: [[EXT:%.*]] = uitofp i32 [[N]] to double
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], double [[EXT]], double 0.000000e+00
+; CHECK-NEXT: ret double [[SELECT]]
+;
+ %cmp = icmp sgt i32 %n, -1
+ %ext = uitofp i32 %n to double
+ %select = select i1 %cmp, double %ext, double 0.0
+ ret double %select
+}
>From f1cf9f8cc98bd8e5f91488655e42e8e648a89e79 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 20 Mar 2024 17:00:47 -0500
Subject: [PATCH 3/4] [CVP] Convert `sitofp` -> `uitofp nneg` and add `nneg`
flag to `uitofp`
Similiar to the `InstCombine` changes, just furthering the scope of
the canonicalization/`uitofp nneg` support
---
.../Scalar/CorrelatedValuePropagation.cpp | 51 ++++++++++++++++---
.../CorrelatedValuePropagation/sitofp.ll | 8 +--
.../CorrelatedValuePropagation/uitofp.ll | 8 +--
3 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index fb334e8292eb18..e6fbcd4b795c55 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -62,6 +62,7 @@ STATISTIC(NumAShrsConverted, "Number of ashr converted to lshr");
STATISTIC(NumAShrsRemoved, "Number of ashr removed");
STATISTIC(NumSRems, "Number of srem converted to urem");
STATISTIC(NumSExt, "Number of sext converted to zext");
+STATISTIC(NumSIToFP, "Number of sitofp converted to uitofp");
STATISTIC(NumSICmps, "Number of signed icmp preds simplified to unsigned");
STATISTIC(NumAnd, "Number of ands removed");
STATISTIC(NumNW, "Number of no-wrap deductions");
@@ -89,7 +90,7 @@ STATISTIC(NumSMinMax,
"Number of llvm.s{min,max} intrinsics simplified to unsigned");
STATISTIC(NumUDivURemsNarrowedExpanded,
"Number of bound udiv's/urem's expanded");
-STATISTIC(NumZExt, "Number of non-negative deductions");
+STATISTIC(NumNNeg, "Number of zext/uitofp non-negative deductions");
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
if (Constant *C = LVI->getConstant(V, At))
@@ -1075,20 +1076,50 @@ static bool processSExt(SExtInst *SDI, LazyValueInfo *LVI) {
return true;
}
-static bool processZExt(ZExtInst *ZExt, LazyValueInfo *LVI) {
- if (ZExt->getType()->isVectorTy())
+static bool processPossibleNonNeg(Instruction *I, LazyValueInfo *LVI) {
+ assert(isa<PossiblyNonNegInst>(I) && "Requires PossiblyNonNeg instruction");
+ if (I->getType()->isVectorTy())
return false;
- if (ZExt->hasNonNeg())
+ if (I->hasNonNeg())
return false;
- const Use &Base = ZExt->getOperandUse(0);
+ const Use &Base = I->getOperandUse(0);
if (!LVI->getConstantRangeAtUse(Base, /*UndefAllowed*/ false)
.isAllNonNegative())
return false;
- ++NumZExt;
- ZExt->setNonNeg();
+ ++NumNNeg;
+ I->setNonNeg();
+
+ return true;
+}
+
+static bool processZExt(ZExtInst *ZExt, LazyValueInfo *LVI) {
+ return processPossibleNonNeg(ZExt, LVI);
+}
+
+static bool processUIToFP(UIToFPInst *UIToFP, LazyValueInfo *LVI) {
+ return processPossibleNonNeg(UIToFP, LVI);
+}
+
+static bool processSIToFP(SIToFPInst *SIToFP, LazyValueInfo *LVI) {
+ if (SIToFP->getType()->isVectorTy())
+ return false;
+
+ const Use &Base = SIToFP->getOperandUse(0);
+ if (!LVI->getConstantRangeAtUse(Base, /*UndefAllowed*/ false)
+ .isAllNonNegative())
+ return false;
+
+ ++NumSIToFP;
+ auto *UIToFP = CastInst::Create(Instruction::UIToFP, Base, SIToFP->getType(),
+ "", SIToFP->getIterator());
+ UIToFP->takeName(SIToFP);
+ UIToFP->setDebugLoc(SIToFP->getDebugLoc());
+ UIToFP->setNonNeg();
+ SIToFP->replaceAllUsesWith(UIToFP);
+ SIToFP->eraseFromParent();
return true;
}
@@ -1200,6 +1231,12 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
case Instruction::ZExt:
BBChanged |= processZExt(cast<ZExtInst>(&II), LVI);
break;
+ case Instruction::UIToFP:
+ BBChanged |= processUIToFP(cast<UIToFPInst>(&II), LVI);
+ break;
+ case Instruction::SIToFP:
+ BBChanged |= processSIToFP(cast<SIToFPInst>(&II), LVI);
+ break;
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll
index 7a49a33fbf9e6c..db8d0a8b80e3bc 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/sitofp.ll
@@ -12,7 +12,7 @@ define void @test1_fptosi(i32 %n) {
; 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:%.*]] = sitofp i32 [[A]] to float
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp nneg i32 [[A]] to float
; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
; CHECK-NEXT: [[EXT]] = fptosi float [[EXT_WIDE]] to i32
; CHECK-NEXT: br label [[FOR_COND]]
@@ -46,7 +46,7 @@ define void @test1_fptoui(i32 %n) {
; 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:%.*]] = sitofp i32 [[A]] to float
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp nneg i32 [[A]] to float
; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
; CHECK-NEXT: [[EXT]] = fptoui float [[EXT_WIDE]] to i32
; CHECK-NEXT: br label [[FOR_COND]]
@@ -113,7 +113,7 @@ define void @test3(i32 %n) {
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
-; CHECK-NEXT: [[EXT_WIDE:%.*]] = sitofp i32 [[N]] to float
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp nneg i32 [[N]] to float
; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
@@ -192,7 +192,7 @@ exit:
define double @test_infer_at_use(i32 noundef %n) {
; CHECK-LABEL: @test_infer_at_use(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
-; CHECK-NEXT: [[EXT:%.*]] = sitofp i32 [[N]] to double
+; CHECK-NEXT: [[EXT:%.*]] = uitofp nneg i32 [[N]] to double
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], double [[EXT]], double 0.000000e+00
; CHECK-NEXT: ret double [[SELECT]]
;
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll
index 1c9dc21c26feb7..8cb3bb366be100 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/uitofp.ll
@@ -12,7 +12,7 @@ define void @test1_fptosi(i32 %n) {
; 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:%.*]] = uitofp i32 [[A]] to float
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp nneg i32 [[A]] to float
; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
; CHECK-NEXT: [[EXT]] = fptosi float [[EXT_WIDE]] to i32
; CHECK-NEXT: br label [[FOR_COND]]
@@ -46,7 +46,7 @@ define void @test1_fptoui(i32 %n) {
; 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:%.*]] = uitofp i32 [[A]] to float
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp nneg i32 [[A]] to float
; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
; CHECK-NEXT: [[EXT]] = fptoui float [[EXT_WIDE]] to i32
; CHECK-NEXT: br label [[FOR_COND]]
@@ -113,7 +113,7 @@ define void @test3(i32 %n) {
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
-; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp i32 [[N]] to float
+; CHECK-NEXT: [[EXT_WIDE:%.*]] = uitofp nneg i32 [[N]] to float
; CHECK-NEXT: call void @use.f32(float [[EXT_WIDE]])
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
@@ -192,7 +192,7 @@ exit:
define double @test_infer_at_use(i32 noundef %n) {
; CHECK-LABEL: @test_infer_at_use(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
-; CHECK-NEXT: [[EXT:%.*]] = uitofp i32 [[N]] to double
+; CHECK-NEXT: [[EXT:%.*]] = uitofp nneg i32 [[N]] to double
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], double [[EXT]], double 0.000000e+00
; CHECK-NEXT: ret double [[SELECT]]
;
>From a0c0a96ee2435eed2a22ff291572d7fbca01dcd6 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 20 Mar 2024 17:05:03 -0500
Subject: [PATCH 4/4] [SCCP] Add `nneg` flag to `uitofp` if its operand is
non-negative
Similiar to the `InstCombine` changes, just furthering the support of
the `uitofp nneg` support.
---
llvm/lib/Transforms/Utils/SCCPSolver.cpp | 12 +++++++-----
llvm/test/Transforms/SCCP/ip-ranges-casts.ll | 8 ++++----
llvm/test/Transforms/SCCP/sitofp.ll | 8 ++++----
3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 38fc7763c5b204..82b8d826301db1 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -140,7 +140,7 @@ static bool refineInstruction(SCCPSolver &Solver,
Changed = true;
}
}
- } else if (isa<ZExtInst>(Inst) && !Inst.hasNonNeg()) {
+ } else if (isa<PossiblyNonNegInst>(Inst) && !Inst.hasNonNeg()) {
auto Range = GetRange(Inst.getOperand(0));
if (Range.isAllNonNegative()) {
Inst.setNonNeg();
@@ -170,14 +170,16 @@ static bool replaceSignedInst(SCCPSolver &Solver,
Instruction *NewInst = nullptr;
switch (Inst.getOpcode()) {
- // Note: We do not fold sitofp -> uitofp here because that could be more
- // expensive in codegen and may not be reversible in the backend.
+ case Instruction::SIToFP:
case Instruction::SExt: {
- // If the source value is not negative, this is a zext.
+ // If the source value is not negative, this is a zext/uitofp.
Value *Op0 = Inst.getOperand(0);
if (InsertedValues.count(Op0) || !isNonNegative(Op0))
return false;
- NewInst = new ZExtInst(Op0, Inst.getType(), "", Inst.getIterator());
+ NewInst = CastInst::Create(Inst.getOpcode() == Instruction::SExt
+ ? Instruction::ZExt
+ : Instruction::UIToFP,
+ Op0, Inst.getType(), "", Inst.getIterator());
NewInst->setNonNeg();
break;
}
diff --git a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
index b97b3a0c458168..3de4822f749a11 100644
--- a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
+++ b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
@@ -163,7 +163,7 @@ define i1 @caller.sext() {
; There's nothing we can do besides going to the full range or overdefined.
define internal i1 @f.fptosi(i32 %x) {
; CHECK-LABEL: @f.fptosi(
-; CHECK-NEXT: [[TO_DOUBLE:%.*]] = sitofp i32 [[X:%.*]] to double
+; CHECK-NEXT: [[TO_DOUBLE:%.*]] = uitofp nneg i32 [[X:%.*]] to double
; CHECK-NEXT: [[ADD:%.*]] = fadd double 0.000000e+00, [[TO_DOUBLE]]
; CHECK-NEXT: [[TO_I32:%.*]] = fptosi double [[ADD]] to i32
; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[TO_I32]], 300
@@ -204,7 +204,7 @@ define i1 @caller.fptosi() {
; There's nothing we can do besides going to the full range or overdefined.
define internal i1 @f.fpext(i16 %x) {
; CHECK-LABEL: @f.fpext(
-; CHECK-NEXT: [[TO_FLOAT:%.*]] = sitofp i16 [[X:%.*]] to float
+; CHECK-NEXT: [[TO_FLOAT:%.*]] = uitofp nneg i16 [[X:%.*]] to float
; CHECK-NEXT: [[TO_DOUBLE:%.*]] = fpext float [[TO_FLOAT]] to double
; CHECK-NEXT: [[TO_I64:%.*]] = fptoui float [[TO_FLOAT]] to i64
; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i64 [[TO_I64]], 300
@@ -286,7 +286,7 @@ define i1 @caller.inttoptr.ptrtoint() {
define i1 @int_range_to_double_cast(i32 %a) {
; CHECK-LABEL: @int_range_to_double_cast(
; CHECK-NEXT: [[R:%.*]] = and i32 [[A:%.*]], 255
-; CHECK-NEXT: [[T4:%.*]] = sitofp i32 [[R]] to double
+; CHECK-NEXT: [[T4:%.*]] = uitofp nneg i32 [[R]] to double
; CHECK-NEXT: [[T10:%.*]] = fadd double 0.000000e+00, [[T4]]
; CHECK-NEXT: [[T11:%.*]] = fcmp olt double [[T4]], [[T10]]
; CHECK-NEXT: ret i1 [[T11]]
@@ -329,7 +329,7 @@ define i64 @caller.sext_to_zext(i32 %i) {
; CHECK-LABEL: @caller.sext_to_zext(
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[I:%.*]], 9
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-; CHECK-NEXT: [[T:%.*]] = call i64 @f.sext_to_zext(i32 [[CONV]])
+; CHECK-NEXT: [[T:%.*]] = call i64 @f.sext_to_zext(i32 [[CONV]]), !range [[RNG0:![0-9]+]]
; CHECK-NEXT: ret i64 [[T]]
;
%cmp = icmp sle i32 %i, 9
diff --git a/llvm/test/Transforms/SCCP/sitofp.ll b/llvm/test/Transforms/SCCP/sitofp.ll
index b635263a5726c2..24f04ae1fccb91 100644
--- a/llvm/test/Transforms/SCCP/sitofp.ll
+++ b/llvm/test/Transforms/SCCP/sitofp.ll
@@ -4,7 +4,7 @@
define float @sitofp_and(i8 %x) {
; CHECK-LABEL: @sitofp_and(
; CHECK-NEXT: [[PX:%.*]] = and i8 [[X:%.*]], 127
-; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[PX]] to float
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[PX]] to float
; CHECK-NEXT: ret float [[R]]
;
%px = and i8 %x, 127
@@ -23,7 +23,7 @@ define half @sitofp_const(i8 %x) {
define double @sitofp_zext(i7 %x) {
; CHECK-LABEL: @sitofp_zext(
; CHECK-NEXT: [[PX:%.*]] = zext i7 [[X:%.*]] to i8
-; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[PX]] to double
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[PX]] to double
; CHECK-NEXT: ret double [[R]]
;
%px = zext i7 %x to i8
@@ -52,7 +52,7 @@ define float @dominating_condition(i32 %x) {
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
-; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to float
+; CHECK-NEXT: [[A:%.*]] = uitofp nneg i32 [[X]] to float
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: f:
; CHECK-NEXT: br label [[EXIT]]
@@ -86,7 +86,7 @@ define float @dominating_condition_alt(i32 %x) {
; CHECK: t:
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: f:
-; CHECK-NEXT: [[A:%.*]] = sitofp i32 [[X]] to float
+; CHECK-NEXT: [[A:%.*]] = uitofp nneg i32 [[X]] to float
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[COND:%.*]] = phi float [ -4.200000e+01, [[T]] ], [ [[A]], [[F]] ]
More information about the cfe-commits
mailing list