[clang] [llvm] [ValueLattice][SCCP] Do not track undefs (PR #107105)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 3 06:18:05 PDT 2024
https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/107105
>From be08a5a9d2e9a56b3e9fa08b970aeec7ee3e2b0e Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 3 Sep 2024 10:11:18 +0200
Subject: [PATCH] [ValueLattice][SCCP] Do not track undefs
SCCP currently has a lot of complexity related to undef tracking.
The reason is that it wants to support undef v constant -> constant
merges, which requires undef -> constant lattice transitions. This
means that we cannot really do any evaluation if an input is undef,
because it might become a constant later. So instead we leave those
values as unknown. But of course that's not correct, because
unknown means the value is poison. As such, is an iterative fixup
stage where we replace those unknowns with overdefined instead.
This PR proposes to stop giving undef special treatment, and
consider it like any other constant instead. This means that
constant v undef now becomes overdefined and we may lose out
on optimizations involving undefs in phis. On the flip side, we
can remove a lot of complexity from SCCP. This PR still keeps
constant_range_including_undef around to reduce scope, but we
should remove that as well, further simplifying things.
---
clang/test/Headers/__clang_hip_math.hip | 452 ++++++++++--------
llvm/include/llvm/Analysis/ValueLattice.h | 71 +--
.../llvm/Transforms/Utils/SCCPSolver.h | 17 +-
llvm/lib/Analysis/ValueLattice.cpp | 7 -
.../Transforms/IPO/FunctionSpecialization.cpp | 5 +-
llvm/lib/Transforms/IPO/SCCP.cpp | 4 +-
llvm/lib/Transforms/Scalar/SCCP.cpp | 7 +-
llvm/lib/Transforms/Utils/SCCPSolver.cpp | 229 ++-------
.../CorrelatedValuePropagation/abs.ll | 3 +-
.../merge-range-and-undef.ll | 42 +-
.../CorrelatedValuePropagation/urem.ll | 2 +-
.../bug52821-use-after-free.ll | 6 +-
.../identical-specializations.ll | 28 +-
llvm/test/Transforms/JumpThreading/pr22086.ll | 5 +-
.../JumpThreading/thread-debug-info.ll | 4 +-
.../condition-phi-unreachable-default.ll | 2 +-
.../constraint-elimination-placement.ll | 4 +-
.../Transforms/SCCP/2006-12-19-UndefBug.ll | 3 +-
llvm/test/Transforms/SCCP/PR16052.ll | 14 +-
llvm/test/Transforms/SCCP/PR26044.ll | 16 +-
llvm/test/Transforms/SCCP/apint-bigint2.ll | 12 +-
llvm/test/Transforms/SCCP/apint-select.ll | 8 +-
.../SCCP/binaryops-range-special-cases.ll | 8 +-
.../SCCP/conditions-ranges-with-undef.ll | 25 +-
llvm/test/Transforms/SCCP/divrem-crash.ll | 6 +-
llvm/test/Transforms/SCCP/float-phis.ll | 4 +-
llvm/test/Transforms/SCCP/int-phis.ll | 6 +-
llvm/test/Transforms/SCCP/intrinsics.ll | 4 +-
.../Transforms/SCCP/ip-constant-ranges.ll | 4 +-
llvm/test/Transforms/SCCP/ipsccp-basic.ll | 11 +-
llvm/test/Transforms/SCCP/loadtest2.ll | 3 +-
llvm/test/Transforms/SCCP/logical-nuke.ll | 8 +-
llvm/test/Transforms/SCCP/overdefined-div.ll | 6 +-
llvm/test/Transforms/SCCP/phi-cycle.ll | 5 +-
llvm/test/Transforms/SCCP/range-and-ip.ll | 9 +-
llvm/test/Transforms/SCCP/range-and.ll | 18 +-
llvm/test/Transforms/SCCP/recursion.ll | 7 +-
.../SCCP/resolvedundefsin-tracked-fn.ll | 38 +-
llvm/test/Transforms/SCCP/return-zapped.ll | 2 +-
llvm/test/Transforms/SCCP/select.ll | 3 +-
llvm/test/Transforms/SCCP/ub-shift.ll | 12 +-
llvm/test/Transforms/SCCP/undef-resolve.ll | 24 +-
llvm/unittests/Analysis/ValueLatticeTest.cpp | 13 +-
.../IPO/FunctionSpecializationTest.cpp | 2 +-
44 files changed, 477 insertions(+), 682 deletions(-)
diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip
index 9d202e0d046822..7b50ea568c74cb 100644
--- a/clang/test/Headers/__clang_hip_math.hip
+++ b/clang/test/Headers/__clang_hip_math.hip
@@ -35,6 +35,7 @@ typedef unsigned long long uint64_t;
// CHECK: while.cond.i:
// CHECK-NEXT: [[__TAGP_ADDR_0_I:%.*]] = phi ptr [ [[P:%.*]], [[ENTRY:%.*]] ], [ [[__TAGP_ADDR_1_I:%.*]], [[CLEANUP_I:%.*]] ]
// CHECK-NEXT: [[__R_0_I:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[__R_1_I:%.*]], [[CLEANUP_I]] ]
+// CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ undef, [[ENTRY]] ], [ [[RETVAL_1_I:%.*]], [[CLEANUP_I]] ]
// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I]], align 1, !tbaa [[TBAA4:![0-9]+]]
// CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
// CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[_ZL21__MAKE_MANTISSA_BASE8PKC_EXIT:%.*]], label [[WHILE_BODY_I:%.*]]
@@ -52,9 +53,10 @@ typedef unsigned long long uint64_t;
// CHECK: cleanup.i:
// CHECK-NEXT: [[__TAGP_ADDR_1_I]] = phi ptr [ [[INCDEC_PTR_I]], [[IF_THEN_I]] ], [ [[__TAGP_ADDR_0_I]], [[WHILE_BODY_I]] ]
// CHECK-NEXT: [[__R_1_I]] = phi i64 [ [[SUB_I]], [[IF_THEN_I]] ], [ [[__R_0_I]], [[WHILE_BODY_I]] ]
+// CHECK-NEXT: [[RETVAL_1_I]] = phi i64 [ [[RETVAL_0_I]], [[IF_THEN_I]] ], [ 0, [[WHILE_BODY_I]] ]
// CHECK-NEXT: br i1 [[OR_COND_I]], label [[WHILE_COND_I]], label [[_ZL21__MAKE_MANTISSA_BASE8PKC_EXIT]], !llvm.loop [[LOOP7:![0-9]+]]
// CHECK: _ZL21__make_mantissa_base8PKc.exit:
-// CHECK-NEXT: [[RETVAL_2_I:%.*]] = phi i64 [ 0, [[CLEANUP_I]] ], [ [[__R_0_I]], [[WHILE_COND_I]] ]
+// CHECK-NEXT: [[RETVAL_2_I:%.*]] = phi i64 [ [[RETVAL_1_I]], [[CLEANUP_I]] ], [ [[__R_0_I]], [[WHILE_COND_I]] ]
// CHECK-NEXT: ret i64 [[RETVAL_2_I]]
//
extern "C" __device__ uint64_t test___make_mantissa_base8(const char *p) {
@@ -67,6 +69,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base8(const char *p) {
// CHECK: while.cond.i:
// CHECK-NEXT: [[__TAGP_ADDR_0_I:%.*]] = phi ptr [ [[P:%.*]], [[ENTRY:%.*]] ], [ [[__TAGP_ADDR_1_I:%.*]], [[CLEANUP_I:%.*]] ]
// CHECK-NEXT: [[__R_0_I:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[__R_1_I:%.*]], [[CLEANUP_I]] ]
+// CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ undef, [[ENTRY]] ], [ [[RETVAL_1_I:%.*]], [[CLEANUP_I]] ]
// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I]], align 1, !tbaa [[TBAA4]]
// CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
// CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[_ZL22__MAKE_MANTISSA_BASE10PKC_EXIT:%.*]], label [[WHILE_BODY_I:%.*]]
@@ -84,9 +87,10 @@ extern "C" __device__ uint64_t test___make_mantissa_base8(const char *p) {
// CHECK: cleanup.i:
// CHECK-NEXT: [[__TAGP_ADDR_1_I]] = phi ptr [ [[INCDEC_PTR_I]], [[IF_THEN_I]] ], [ [[__TAGP_ADDR_0_I]], [[WHILE_BODY_I]] ]
// CHECK-NEXT: [[__R_1_I]] = phi i64 [ [[SUB_I]], [[IF_THEN_I]] ], [ [[__R_0_I]], [[WHILE_BODY_I]] ]
+// CHECK-NEXT: [[RETVAL_1_I]] = phi i64 [ [[RETVAL_0_I]], [[IF_THEN_I]] ], [ 0, [[WHILE_BODY_I]] ]
// CHECK-NEXT: br i1 [[OR_COND_I]], label [[WHILE_COND_I]], label [[_ZL22__MAKE_MANTISSA_BASE10PKC_EXIT]], !llvm.loop [[LOOP10:![0-9]+]]
// CHECK: _ZL22__make_mantissa_base10PKc.exit:
-// CHECK-NEXT: [[RETVAL_2_I:%.*]] = phi i64 [ 0, [[CLEANUP_I]] ], [ [[__R_0_I]], [[WHILE_COND_I]] ]
+// CHECK-NEXT: [[RETVAL_2_I:%.*]] = phi i64 [ [[RETVAL_1_I]], [[CLEANUP_I]] ], [ [[__R_0_I]], [[WHILE_COND_I]] ]
// CHECK-NEXT: ret i64 [[RETVAL_2_I]]
//
extern "C" __device__ uint64_t test___make_mantissa_base10(const char *p) {
@@ -99,6 +103,7 @@ extern "C" __device__ uint64_t test___make_mantissa_base10(const char *p) {
// CHECK: while.cond.i:
// CHECK-NEXT: [[__TAGP_ADDR_0_I:%.*]] = phi ptr [ [[P:%.*]], [[ENTRY:%.*]] ], [ [[__TAGP_ADDR_1_I:%.*]], [[CLEANUP_I:%.*]] ]
// CHECK-NEXT: [[__R_0_I:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[__R_2_I:%.*]], [[CLEANUP_I]] ]
+// CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ undef, [[ENTRY]] ], [ [[RETVAL_1_I:%.*]], [[CLEANUP_I]] ]
// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I]], align 1, !tbaa [[TBAA4]]
// CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
// CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[_ZL22__MAKE_MANTISSA_BASE16PKC_EXIT:%.*]], label [[WHILE_BODY_I:%.*]]
@@ -125,10 +130,11 @@ extern "C" __device__ uint64_t test___make_mantissa_base10(const char *p) {
// CHECK: cleanup.i:
// CHECK-NEXT: [[__TAGP_ADDR_1_I]] = phi ptr [ [[INCDEC_PTR_I]], [[IF_END31_I]] ], [ [[__TAGP_ADDR_0_I]], [[IF_ELSE17_I]] ]
// CHECK-NEXT: [[__R_2_I]] = phi i64 [ [[ADD28_I]], [[IF_END31_I]] ], [ [[__R_0_I]], [[IF_ELSE17_I]] ]
+// CHECK-NEXT: [[RETVAL_1_I]] = phi i64 [ [[RETVAL_0_I]], [[IF_END31_I]] ], [ 0, [[IF_ELSE17_I]] ]
// CHECK-NEXT: [[COND_I:%.*]] = phi i1 [ true, [[IF_END31_I]] ], [ false, [[IF_ELSE17_I]] ]
// CHECK-NEXT: br i1 [[COND_I]], label [[WHILE_COND_I]], label [[_ZL22__MAKE_MANTISSA_BASE16PKC_EXIT]], !llvm.loop [[LOOP11:![0-9]+]]
// CHECK: _ZL22__make_mantissa_base16PKc.exit:
-// CHECK-NEXT: [[RETVAL_2_I:%.*]] = phi i64 [ 0, [[CLEANUP_I]] ], [ [[__R_0_I]], [[WHILE_COND_I]] ]
+// CHECK-NEXT: [[RETVAL_2_I:%.*]] = phi i64 [ [[RETVAL_1_I]], [[CLEANUP_I]] ], [ [[__R_0_I]], [[WHILE_COND_I]] ]
// CHECK-NEXT: ret i64 [[RETVAL_2_I]]
//
extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) {
@@ -144,21 +150,22 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) {
// CHECK-NEXT: [[INCDEC_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I]], align 1, !tbaa [[TBAA4]]
// CHECK-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I:%.*]] [
-// CHECK-NEXT: i8 120, label [[WHILE_COND_I30_I_PREHEADER:%.*]]
-// CHECK-NEXT: i8 88, label [[WHILE_COND_I30_I_PREHEADER]]
+// CHECK-NEXT: i8 120, label [[WHILE_COND_I32_I_PREHEADER:%.*]]
+// CHECK-NEXT: i8 88, label [[WHILE_COND_I32_I_PREHEADER]]
// CHECK-NEXT: ]
-// CHECK: while.cond.i30.i.preheader:
-// CHECK-NEXT: br label [[WHILE_COND_I30_I:%.*]]
-// CHECK: while.cond.i30.i:
-// CHECK-NEXT: [[__TAGP_ADDR_0_I31_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I37_I:%.*]], [[CLEANUP_I36_I:%.*]] ], [ [[INCDEC_PTR_I]], [[WHILE_COND_I30_I_PREHEADER]] ]
-// CHECK-NEXT: [[__R_0_I32_I:%.*]] = phi i64 [ [[__R_2_I_I:%.*]], [[CLEANUP_I36_I]] ], [ 0, [[WHILE_COND_I30_I_PREHEADER]] ]
-// CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I31_I]], align 1, !tbaa [[TBAA4]]
-// CHECK-NEXT: [[CMP_NOT_I33_I:%.*]] = icmp eq i8 [[TMP2]], 0
-// CHECK-NEXT: br i1 [[CMP_NOT_I33_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT:%.*]], label [[WHILE_BODY_I34_I:%.*]]
-// CHECK: while.body.i34.i:
+// CHECK: while.cond.i32.i.preheader:
+// CHECK-NEXT: br label [[WHILE_COND_I32_I:%.*]]
+// CHECK: while.cond.i32.i:
+// CHECK-NEXT: [[__TAGP_ADDR_0_I33_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I40_I:%.*]], [[CLEANUP_I39_I:%.*]] ], [ [[INCDEC_PTR_I]], [[WHILE_COND_I32_I_PREHEADER]] ]
+// CHECK-NEXT: [[__R_0_I34_I:%.*]] = phi i64 [ [[__R_2_I_I:%.*]], [[CLEANUP_I39_I]] ], [ 0, [[WHILE_COND_I32_I_PREHEADER]] ]
+// CHECK-NEXT: [[RETVAL_0_I35_I:%.*]] = phi i64 [ [[RETVAL_1_I41_I:%.*]], [[CLEANUP_I39_I]] ], [ undef, [[WHILE_COND_I32_I_PREHEADER]] ]
+// CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I33_I]], align 1, !tbaa [[TBAA4]]
+// CHECK-NEXT: [[CMP_NOT_I36_I:%.*]] = icmp eq i8 [[TMP2]], 0
+// CHECK-NEXT: br i1 [[CMP_NOT_I36_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT:%.*]], label [[WHILE_BODY_I37_I:%.*]]
+// CHECK: while.body.i37.i:
// CHECK-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], -48
-// CHECK-NEXT: [[OR_COND_I35_I:%.*]] = icmp ult i8 [[TMP3]], 10
-// CHECK-NEXT: br i1 [[OR_COND_I35_I]], label [[IF_END31_I_I:%.*]], label [[IF_ELSE_I_I:%.*]]
+// CHECK-NEXT: [[OR_COND_I38_I:%.*]] = icmp ult i8 [[TMP3]], 10
+// CHECK-NEXT: br i1 [[OR_COND_I38_I]], label [[IF_END31_I_I:%.*]], label [[IF_ELSE_I_I:%.*]]
// CHECK: if.else.i.i:
// CHECK-NEXT: [[TMP4:%.*]] = add i8 [[TMP2]], -97
// CHECK-NEXT: [[OR_COND33_I_I:%.*]] = icmp ult i8 [[TMP4]], 6
@@ -166,23 +173,25 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) {
// CHECK: if.else17.i.i:
// CHECK-NEXT: [[TMP5:%.*]] = add i8 [[TMP2]], -65
// CHECK-NEXT: [[OR_COND34_I_I:%.*]] = icmp ult i8 [[TMP5]], 6
-// CHECK-NEXT: br i1 [[OR_COND34_I_I]], label [[IF_END31_I_I]], label [[CLEANUP_I36_I]]
+// CHECK-NEXT: br i1 [[OR_COND34_I_I]], label [[IF_END31_I_I]], label [[CLEANUP_I39_I]]
// CHECK: if.end31.i.i:
-// CHECK-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I34_I]] ], [ -87, [[IF_ELSE_I_I]] ], [ -55, [[IF_ELSE17_I_I]] ]
-// CHECK-NEXT: [[MUL24_I_I:%.*]] = shl i64 [[__R_0_I32_I]], 4
+// CHECK-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I37_I]] ], [ -87, [[IF_ELSE_I_I]] ], [ -55, [[IF_ELSE17_I_I]] ]
+// CHECK-NEXT: [[MUL24_I_I:%.*]] = shl i64 [[__R_0_I34_I]], 4
// CHECK-NEXT: [[CONV25_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64
// CHECK-NEXT: [[ADD26_I_I:%.*]] = add i64 [[MUL24_I_I]], [[DOTSINK]]
// CHECK-NEXT: [[ADD28_I_I:%.*]] = add i64 [[ADD26_I_I]], [[CONV25_I_I]]
-// CHECK-NEXT: [[INCDEC_PTR_I40_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I]], i64 1
-// CHECK-NEXT: br label [[CLEANUP_I36_I]]
-// CHECK: cleanup.i36.i:
-// CHECK-NEXT: [[__TAGP_ADDR_1_I37_I]] = phi ptr [ [[INCDEC_PTR_I40_I]], [[IF_END31_I_I]] ], [ [[__TAGP_ADDR_0_I31_I]], [[IF_ELSE17_I_I]] ]
-// CHECK-NEXT: [[__R_2_I_I]] = phi i64 [ [[ADD28_I_I]], [[IF_END31_I_I]] ], [ [[__R_0_I32_I]], [[IF_ELSE17_I_I]] ]
+// CHECK-NEXT: [[INCDEC_PTR_I44_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I33_I]], i64 1
+// CHECK-NEXT: br label [[CLEANUP_I39_I]]
+// CHECK: cleanup.i39.i:
+// CHECK-NEXT: [[__TAGP_ADDR_1_I40_I]] = phi ptr [ [[INCDEC_PTR_I44_I]], [[IF_END31_I_I]] ], [ [[__TAGP_ADDR_0_I33_I]], [[IF_ELSE17_I_I]] ]
+// CHECK-NEXT: [[__R_2_I_I]] = phi i64 [ [[ADD28_I_I]], [[IF_END31_I_I]] ], [ [[__R_0_I34_I]], [[IF_ELSE17_I_I]] ]
+// CHECK-NEXT: [[RETVAL_1_I41_I]] = phi i64 [ [[RETVAL_0_I35_I]], [[IF_END31_I_I]] ], [ 0, [[IF_ELSE17_I_I]] ]
// CHECK-NEXT: [[COND_I_I:%.*]] = phi i1 [ true, [[IF_END31_I_I]] ], [ false, [[IF_ELSE17_I_I]] ]
-// CHECK-NEXT: br i1 [[COND_I_I]], label [[WHILE_COND_I30_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], !llvm.loop [[LOOP11]]
+// CHECK-NEXT: br i1 [[COND_I_I]], label [[WHILE_COND_I32_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], !llvm.loop [[LOOP11]]
// CHECK: while.cond.i.i:
// CHECK-NEXT: [[__TAGP_ADDR_0_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I_I:%.*]], [[CLEANUP_I_I:%.*]] ], [ [[INCDEC_PTR_I]], [[IF_THEN_I]] ]
// CHECK-NEXT: [[__R_0_I_I:%.*]] = phi i64 [ [[__R_1_I_I:%.*]], [[CLEANUP_I_I]] ], [ 0, [[IF_THEN_I]] ]
+// CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I:%.*]], [[CLEANUP_I_I]] ], [ undef, [[IF_THEN_I]] ]
// CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I_I]], align 1, !tbaa [[TBAA4]]
// CHECK-NEXT: [[CMP_NOT_I_I:%.*]] = icmp eq i8 [[TMP6]], 0
// CHECK-NEXT: br i1 [[CMP_NOT_I_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], label [[WHILE_BODY_I_I:%.*]]
@@ -200,30 +209,33 @@ extern "C" __device__ uint64_t test___make_mantissa_base16(const char *p) {
// CHECK: cleanup.i.i:
// CHECK-NEXT: [[__TAGP_ADDR_1_I_I]] = phi ptr [ [[INCDEC_PTR_I_I]], [[IF_THEN_I_I]] ], [ [[__TAGP_ADDR_0_I_I]], [[WHILE_BODY_I_I]] ]
// CHECK-NEXT: [[__R_1_I_I]] = phi i64 [ [[SUB_I_I]], [[IF_THEN_I_I]] ], [ [[__R_0_I_I]], [[WHILE_BODY_I_I]] ]
+// CHECK-NEXT: [[RETVAL_1_I_I]] = phi i64 [ [[RETVAL_0_I_I]], [[IF_THEN_I_I]] ], [ 0, [[WHILE_BODY_I_I]] ]
// CHECK-NEXT: br i1 [[OR_COND_I_I]], label [[WHILE_COND_I_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], !llvm.loop [[LOOP7]]
// CHECK: while.cond.i14.i:
-// CHECK-NEXT: [[__TAGP_ADDR_0_I15_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I21_I:%.*]], [[CLEANUP_I20_I:%.*]] ], [ [[P]], [[ENTRY:%.*]] ]
-// CHECK-NEXT: [[__R_0_I16_I:%.*]] = phi i64 [ [[__R_1_I22_I:%.*]], [[CLEANUP_I20_I]] ], [ 0, [[ENTRY]] ]
+// CHECK-NEXT: [[__TAGP_ADDR_0_I15_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I22_I:%.*]], [[CLEANUP_I21_I:%.*]] ], [ [[P]], [[ENTRY:%.*]] ]
+// CHECK-NEXT: [[__R_0_I16_I:%.*]] = phi i64 [ [[__R_1_I23_I:%.*]], [[CLEANUP_I21_I]] ], [ 0, [[ENTRY]] ]
+// CHECK-NEXT: [[RETVAL_0_I17_I:%.*]] = phi i64 [ [[RETVAL_1_I24_I:%.*]], [[CLEANUP_I21_I]] ], [ undef, [[ENTRY]] ]
// CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I15_I]], align 1, !tbaa [[TBAA4]]
-// CHECK-NEXT: [[CMP_NOT_I17_I:%.*]] = icmp eq i8 [[TMP8]], 0
-// CHECK-NEXT: br i1 [[CMP_NOT_I17_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], label [[WHILE_BODY_I18_I:%.*]]
-// CHECK: while.body.i18.i:
+// CHECK-NEXT: [[CMP_NOT_I18_I:%.*]] = icmp eq i8 [[TMP8]], 0
+// CHECK-NEXT: br i1 [[CMP_NOT_I18_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], label [[WHILE_BODY_I19_I:%.*]]
+// CHECK: while.body.i19.i:
// CHECK-NEXT: [[TMP9:%.*]] = add i8 [[TMP8]], -48
-// CHECK-NEXT: [[OR_COND_I19_I:%.*]] = icmp ult i8 [[TMP9]], 10
-// CHECK-NEXT: br i1 [[OR_COND_I19_I]], label [[IF_THEN_I24_I:%.*]], label [[CLEANUP_I20_I]]
-// CHECK: if.then.i24.i:
-// CHECK-NEXT: [[MUL_I25_I:%.*]] = mul i64 [[__R_0_I16_I]], 10
-// CHECK-NEXT: [[CONV5_I26_I:%.*]] = zext nneg i8 [[TMP8]] to i64
-// CHECK-NEXT: [[ADD_I27_I:%.*]] = add i64 [[MUL_I25_I]], -48
-// CHECK-NEXT: [[SUB_I28_I:%.*]] = add i64 [[ADD_I27_I]], [[CONV5_I26_I]]
-// CHECK-NEXT: [[INCDEC_PTR_I29_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I]], i64 1
-// CHECK-NEXT: br label [[CLEANUP_I20_I]]
-// CHECK: cleanup.i20.i:
-// CHECK-NEXT: [[__TAGP_ADDR_1_I21_I]] = phi ptr [ [[INCDEC_PTR_I29_I]], [[IF_THEN_I24_I]] ], [ [[__TAGP_ADDR_0_I15_I]], [[WHILE_BODY_I18_I]] ]
-// CHECK-NEXT: [[__R_1_I22_I]] = phi i64 [ [[SUB_I28_I]], [[IF_THEN_I24_I]] ], [ [[__R_0_I16_I]], [[WHILE_BODY_I18_I]] ]
-// CHECK-NEXT: br i1 [[OR_COND_I19_I]], label [[WHILE_COND_I14_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], !llvm.loop [[LOOP10]]
+// CHECK-NEXT: [[OR_COND_I20_I:%.*]] = icmp ult i8 [[TMP9]], 10
+// CHECK-NEXT: br i1 [[OR_COND_I20_I]], label [[IF_THEN_I26_I:%.*]], label [[CLEANUP_I21_I]]
+// CHECK: if.then.i26.i:
+// CHECK-NEXT: [[MUL_I27_I:%.*]] = mul i64 [[__R_0_I16_I]], 10
+// CHECK-NEXT: [[CONV5_I28_I:%.*]] = zext nneg i8 [[TMP8]] to i64
+// CHECK-NEXT: [[ADD_I29_I:%.*]] = add i64 [[MUL_I27_I]], -48
+// CHECK-NEXT: [[SUB_I30_I:%.*]] = add i64 [[ADD_I29_I]], [[CONV5_I28_I]]
+// CHECK-NEXT: [[INCDEC_PTR_I31_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I]], i64 1
+// CHECK-NEXT: br label [[CLEANUP_I21_I]]
+// CHECK: cleanup.i21.i:
+// CHECK-NEXT: [[__TAGP_ADDR_1_I22_I]] = phi ptr [ [[INCDEC_PTR_I31_I]], [[IF_THEN_I26_I]] ], [ [[__TAGP_ADDR_0_I15_I]], [[WHILE_BODY_I19_I]] ]
+// CHECK-NEXT: [[__R_1_I23_I]] = phi i64 [ [[SUB_I30_I]], [[IF_THEN_I26_I]] ], [ [[__R_0_I16_I]], [[WHILE_BODY_I19_I]] ]
+// CHECK-NEXT: [[RETVAL_1_I24_I]] = phi i64 [ [[RETVAL_0_I17_I]], [[IF_THEN_I26_I]] ], [ 0, [[WHILE_BODY_I19_I]] ]
+// CHECK-NEXT: br i1 [[OR_COND_I20_I]], label [[WHILE_COND_I14_I]], label [[_ZL15__MAKE_MANTISSAPKC_EXIT]], !llvm.loop [[LOOP10]]
// CHECK: _ZL15__make_mantissaPKc.exit:
-// CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ 0, [[CLEANUP_I_I]] ], [ [[__R_0_I_I]], [[WHILE_COND_I_I]] ], [ 0, [[CLEANUP_I36_I]] ], [ [[__R_0_I32_I]], [[WHILE_COND_I30_I]] ], [ 0, [[CLEANUP_I20_I]] ], [ [[__R_0_I16_I]], [[WHILE_COND_I14_I]] ]
+// CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ [[RETVAL_1_I_I]], [[CLEANUP_I_I]] ], [ [[__R_0_I_I]], [[WHILE_COND_I_I]] ], [ [[RETVAL_1_I41_I]], [[CLEANUP_I39_I]] ], [ [[__R_0_I34_I]], [[WHILE_COND_I32_I]] ], [ [[RETVAL_1_I24_I]], [[CLEANUP_I21_I]] ], [ [[__R_0_I16_I]], [[WHILE_COND_I14_I]] ]
// CHECK-NEXT: ret i64 [[RETVAL_0_I]]
//
extern "C" __device__ uint64_t test___make_mantissa(const char *p) {
@@ -2370,21 +2382,22 @@ extern "C" __device__ double test_modf(double x, double* y) {
// DEFAULT-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1
// DEFAULT-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]]
// DEFAULT-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [
-// DEFAULT-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]]
-// DEFAULT-NEXT: i8 88, label [[WHILE_COND_I30_I_I_PREHEADER]]
+// DEFAULT-NEXT: i8 120, label [[WHILE_COND_I32_I_I_PREHEADER:%.*]]
+// DEFAULT-NEXT: i8 88, label [[WHILE_COND_I32_I_I_PREHEADER]]
// DEFAULT-NEXT: ]
-// DEFAULT: while.cond.i30.i.i.preheader:
-// DEFAULT-NEXT: br label [[WHILE_COND_I30_I_I:%.*]]
-// DEFAULT: while.cond.i30.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_0_I31_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I37_I_I:%.*]], [[CLEANUP_I36_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// DEFAULT-NEXT: [[__R_0_I32_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I36_I_I]] ], [ 0, [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// DEFAULT-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I31_I_I]], align 1, !tbaa [[TBAA4]]
-// DEFAULT-NEXT: [[CMP_NOT_I33_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
-// DEFAULT-NEXT: br i1 [[CMP_NOT_I33_I_I]], label [[_ZL4NANFPKC_EXIT:%.*]], label [[WHILE_BODY_I34_I_I:%.*]]
-// DEFAULT: while.body.i34.i.i:
+// DEFAULT: while.cond.i32.i.i.preheader:
+// DEFAULT-NEXT: br label [[WHILE_COND_I32_I_I:%.*]]
+// DEFAULT: while.cond.i32.i.i:
+// DEFAULT-NEXT: [[__TAGP_ADDR_0_I33_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I40_I_I:%.*]], [[CLEANUP_I39_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// DEFAULT-NEXT: [[__R_0_I34_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ 0, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I35_I_I:%.*]] = phi i64 [ [[RETVAL_1_I41_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ undef, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// DEFAULT-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I33_I_I]], align 1, !tbaa [[TBAA4]]
+// DEFAULT-NEXT: [[CMP_NOT_I36_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
+// DEFAULT-NEXT: br i1 [[CMP_NOT_I36_I_I]], label [[_ZL4NANFPKC_EXIT:%.*]], label [[WHILE_BODY_I37_I_I:%.*]]
+// DEFAULT: while.body.i37.i.i:
// DEFAULT-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], -48
-// DEFAULT-NEXT: [[OR_COND_I35_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
-// DEFAULT-NEXT: br i1 [[OR_COND_I35_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
+// DEFAULT-NEXT: [[OR_COND_I38_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
+// DEFAULT-NEXT: br i1 [[OR_COND_I38_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
// DEFAULT: if.else.i.i.i:
// DEFAULT-NEXT: [[TMP4:%.*]] = add i8 [[TMP2]], -97
// DEFAULT-NEXT: [[OR_COND33_I_I_I:%.*]] = icmp ult i8 [[TMP4]], 6
@@ -2392,23 +2405,25 @@ extern "C" __device__ double test_modf(double x, double* y) {
// DEFAULT: if.else17.i.i.i:
// DEFAULT-NEXT: [[TMP5:%.*]] = add i8 [[TMP2]], -65
// DEFAULT-NEXT: [[OR_COND34_I_I_I:%.*]] = icmp ult i8 [[TMP5]], 6
-// DEFAULT-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I36_I_I]]
+// DEFAULT-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I39_I_I]]
// DEFAULT: if.end31.i.i.i:
-// DEFAULT-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I34_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
-// DEFAULT-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I32_I_I]], 4
+// DEFAULT-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I37_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I34_I_I]], 4
// DEFAULT-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64
// DEFAULT-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]]
// DEFAULT-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]]
-// DEFAULT-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1
-// DEFAULT-NEXT: br label [[CLEANUP_I36_I_I]]
-// DEFAULT: cleanup.i36.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ]
-// DEFAULT-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I32_I_I]], [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[INCDEC_PTR_I44_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I33_I_I]], i64 1
+// DEFAULT-NEXT: br label [[CLEANUP_I39_I_I]]
+// DEFAULT: cleanup.i39.i.i:
+// DEFAULT-NEXT: [[__TAGP_ADDR_1_I40_I_I]] = phi ptr [ [[INCDEC_PTR_I44_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I33_I_I]], [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I34_I_I]], [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_1_I41_I_I]] = phi i64 [ [[RETVAL_0_I35_I_I]], [[IF_END31_I_I_I]] ], [ 0, [[IF_ELSE17_I_I_I]] ]
// DEFAULT-NEXT: [[COND_I_I_I:%.*]] = phi i1 [ true, [[IF_END31_I_I_I]] ], [ false, [[IF_ELSE17_I_I_I]] ]
-// DEFAULT-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I30_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP11]]
+// DEFAULT-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I32_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP11]]
// DEFAULT: while.cond.i.i.i:
// DEFAULT-NEXT: [[__TAGP_ADDR_0_I_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I_I_I:%.*]], [[CLEANUP_I_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[IF_THEN_I_I]] ]
// DEFAULT-NEXT: [[__R_0_I_I_I:%.*]] = phi i64 [ [[__R_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ 0, [[IF_THEN_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ undef, [[IF_THEN_I_I]] ]
// DEFAULT-NEXT: [[TMP6:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I_I_I]], align 1, !tbaa [[TBAA4]]
// DEFAULT-NEXT: [[CMP_NOT_I_I_I:%.*]] = icmp eq i8 [[TMP6]], 0
// DEFAULT-NEXT: br i1 [[CMP_NOT_I_I_I]], label [[_ZL4NANFPKC_EXIT]], label [[WHILE_BODY_I_I_I:%.*]]
@@ -2426,30 +2441,33 @@ extern "C" __device__ double test_modf(double x, double* y) {
// DEFAULT: cleanup.i.i.i:
// DEFAULT-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
// DEFAULT-NEXT: [[__R_1_I_I_I]] = phi i64 [ [[SUB_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_1_I_I_I]] = phi i64 [ [[RETVAL_0_I_I_I]], [[IF_THEN_I_I_I]] ], [ 0, [[WHILE_BODY_I_I_I]] ]
// DEFAULT-NEXT: br i1 [[OR_COND_I_I_I]], label [[WHILE_COND_I_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP7]]
// DEFAULT: while.cond.i14.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I21_I_I:%.*]], [[CLEANUP_I20_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
-// DEFAULT-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I22_I_I:%.*]], [[CLEANUP_I20_I_I]] ], [ 0, [[ENTRY]] ]
+// DEFAULT-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I22_I_I:%.*]], [[CLEANUP_I21_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
+// DEFAULT-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I23_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ 0, [[ENTRY]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I17_I_I:%.*]] = phi i64 [ [[RETVAL_1_I24_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ undef, [[ENTRY]] ]
// DEFAULT-NEXT: [[TMP8:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I15_I_I]], align 1, !tbaa [[TBAA4]]
-// DEFAULT-NEXT: [[CMP_NOT_I17_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
-// DEFAULT-NEXT: br i1 [[CMP_NOT_I17_I_I]], label [[_ZL4NANFPKC_EXIT]], label [[WHILE_BODY_I18_I_I:%.*]]
-// DEFAULT: while.body.i18.i.i:
+// DEFAULT-NEXT: [[CMP_NOT_I18_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
+// DEFAULT-NEXT: br i1 [[CMP_NOT_I18_I_I]], label [[_ZL4NANFPKC_EXIT]], label [[WHILE_BODY_I19_I_I:%.*]]
+// DEFAULT: while.body.i19.i.i:
// DEFAULT-NEXT: [[TMP9:%.*]] = add i8 [[TMP8]], -48
-// DEFAULT-NEXT: [[OR_COND_I19_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
-// DEFAULT-NEXT: br i1 [[OR_COND_I19_I_I]], label [[IF_THEN_I24_I_I:%.*]], label [[CLEANUP_I20_I_I]]
-// DEFAULT: if.then.i24.i.i:
-// DEFAULT-NEXT: [[MUL_I25_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
-// DEFAULT-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
-// DEFAULT-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48
-// DEFAULT-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]]
-// DEFAULT-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
-// DEFAULT-NEXT: br label [[CLEANUP_I20_I_I]]
-// DEFAULT: cleanup.i20.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// DEFAULT-NEXT: [[__R_1_I22_I_I]] = phi i64 [ [[SUB_I28_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// DEFAULT-NEXT: br i1 [[OR_COND_I19_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP10]]
+// DEFAULT-NEXT: [[OR_COND_I20_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
+// DEFAULT-NEXT: br i1 [[OR_COND_I20_I_I]], label [[IF_THEN_I26_I_I:%.*]], label [[CLEANUP_I21_I_I]]
+// DEFAULT: if.then.i26.i.i:
+// DEFAULT-NEXT: [[MUL_I27_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
+// DEFAULT-NEXT: [[CONV5_I28_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
+// DEFAULT-NEXT: [[ADD_I29_I_I:%.*]] = add i64 [[MUL_I27_I_I]], -48
+// DEFAULT-NEXT: [[SUB_I30_I_I:%.*]] = add i64 [[ADD_I29_I_I]], [[CONV5_I28_I_I]]
+// DEFAULT-NEXT: [[INCDEC_PTR_I31_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
+// DEFAULT-NEXT: br label [[CLEANUP_I21_I_I]]
+// DEFAULT: cleanup.i21.i.i:
+// DEFAULT-NEXT: [[__TAGP_ADDR_1_I22_I_I]] = phi ptr [ [[INCDEC_PTR_I31_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// DEFAULT-NEXT: [[__R_1_I23_I_I]] = phi i64 [ [[SUB_I30_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_1_I24_I_I]] = phi i64 [ [[RETVAL_0_I17_I_I]], [[IF_THEN_I26_I_I]] ], [ 0, [[WHILE_BODY_I19_I_I]] ]
+// DEFAULT-NEXT: br i1 [[OR_COND_I20_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP10]]
// DEFAULT: _ZL4nanfPKc.exit:
-// DEFAULT-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ 0, [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ 0, [[CLEANUP_I36_I_I]] ], [ [[__R_0_I32_I_I]], [[WHILE_COND_I30_I_I]] ], [ 0, [[CLEANUP_I20_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I]], [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ [[RETVAL_1_I41_I_I]], [[CLEANUP_I39_I_I]] ], [ [[__R_0_I34_I_I]], [[WHILE_COND_I32_I_I]] ], [ [[RETVAL_1_I24_I_I]], [[CLEANUP_I21_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
// DEFAULT-NEXT: [[CONV_I:%.*]] = trunc i64 [[RETVAL_0_I_I]] to i32
// DEFAULT-NEXT: [[BF_VALUE_I:%.*]] = and i32 [[CONV_I]], 4194303
// DEFAULT-NEXT: [[BF_SET9_I:%.*]] = or disjoint i32 [[BF_VALUE_I]], 2143289344
@@ -2469,21 +2487,22 @@ extern "C" __device__ double test_modf(double x, double* y) {
// APPROX-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1
// APPROX-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]]
// APPROX-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [
-// APPROX-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]]
-// APPROX-NEXT: i8 88, label [[WHILE_COND_I30_I_I_PREHEADER]]
+// APPROX-NEXT: i8 120, label [[WHILE_COND_I32_I_I_PREHEADER:%.*]]
+// APPROX-NEXT: i8 88, label [[WHILE_COND_I32_I_I_PREHEADER]]
// APPROX-NEXT: ]
-// APPROX: while.cond.i30.i.i.preheader:
-// APPROX-NEXT: br label [[WHILE_COND_I30_I_I:%.*]]
-// APPROX: while.cond.i30.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_0_I31_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I37_I_I:%.*]], [[CLEANUP_I36_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// APPROX-NEXT: [[__R_0_I32_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I36_I_I]] ], [ 0, [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// APPROX-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I31_I_I]], align 1, !tbaa [[TBAA4]]
-// APPROX-NEXT: [[CMP_NOT_I33_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
-// APPROX-NEXT: br i1 [[CMP_NOT_I33_I_I]], label [[_ZL4NANFPKC_EXIT:%.*]], label [[WHILE_BODY_I34_I_I:%.*]]
-// APPROX: while.body.i34.i.i:
+// APPROX: while.cond.i32.i.i.preheader:
+// APPROX-NEXT: br label [[WHILE_COND_I32_I_I:%.*]]
+// APPROX: while.cond.i32.i.i:
+// APPROX-NEXT: [[__TAGP_ADDR_0_I33_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I40_I_I:%.*]], [[CLEANUP_I39_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// APPROX-NEXT: [[__R_0_I34_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ 0, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// APPROX-NEXT: [[RETVAL_0_I35_I_I:%.*]] = phi i64 [ [[RETVAL_1_I41_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ undef, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// APPROX-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I33_I_I]], align 1, !tbaa [[TBAA4]]
+// APPROX-NEXT: [[CMP_NOT_I36_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
+// APPROX-NEXT: br i1 [[CMP_NOT_I36_I_I]], label [[_ZL4NANFPKC_EXIT:%.*]], label [[WHILE_BODY_I37_I_I:%.*]]
+// APPROX: while.body.i37.i.i:
// APPROX-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], -48
-// APPROX-NEXT: [[OR_COND_I35_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
-// APPROX-NEXT: br i1 [[OR_COND_I35_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
+// APPROX-NEXT: [[OR_COND_I38_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
+// APPROX-NEXT: br i1 [[OR_COND_I38_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
// APPROX: if.else.i.i.i:
// APPROX-NEXT: [[TMP4:%.*]] = add i8 [[TMP2]], -97
// APPROX-NEXT: [[OR_COND33_I_I_I:%.*]] = icmp ult i8 [[TMP4]], 6
@@ -2491,23 +2510,25 @@ extern "C" __device__ double test_modf(double x, double* y) {
// APPROX: if.else17.i.i.i:
// APPROX-NEXT: [[TMP5:%.*]] = add i8 [[TMP2]], -65
// APPROX-NEXT: [[OR_COND34_I_I_I:%.*]] = icmp ult i8 [[TMP5]], 6
-// APPROX-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I36_I_I]]
+// APPROX-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I39_I_I]]
// APPROX: if.end31.i.i.i:
-// APPROX-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I34_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
-// APPROX-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I32_I_I]], 4
+// APPROX-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I37_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I34_I_I]], 4
// APPROX-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64
// APPROX-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]]
// APPROX-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]]
-// APPROX-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1
-// APPROX-NEXT: br label [[CLEANUP_I36_I_I]]
-// APPROX: cleanup.i36.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ]
-// APPROX-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I32_I_I]], [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[INCDEC_PTR_I44_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I33_I_I]], i64 1
+// APPROX-NEXT: br label [[CLEANUP_I39_I_I]]
+// APPROX: cleanup.i39.i.i:
+// APPROX-NEXT: [[__TAGP_ADDR_1_I40_I_I]] = phi ptr [ [[INCDEC_PTR_I44_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I33_I_I]], [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I34_I_I]], [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[RETVAL_1_I41_I_I]] = phi i64 [ [[RETVAL_0_I35_I_I]], [[IF_END31_I_I_I]] ], [ 0, [[IF_ELSE17_I_I_I]] ]
// APPROX-NEXT: [[COND_I_I_I:%.*]] = phi i1 [ true, [[IF_END31_I_I_I]] ], [ false, [[IF_ELSE17_I_I_I]] ]
-// APPROX-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I30_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP11]]
+// APPROX-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I32_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP11]]
// APPROX: while.cond.i.i.i:
// APPROX-NEXT: [[__TAGP_ADDR_0_I_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I_I_I:%.*]], [[CLEANUP_I_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[IF_THEN_I_I]] ]
// APPROX-NEXT: [[__R_0_I_I_I:%.*]] = phi i64 [ [[__R_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ 0, [[IF_THEN_I_I]] ]
+// APPROX-NEXT: [[RETVAL_0_I_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ undef, [[IF_THEN_I_I]] ]
// APPROX-NEXT: [[TMP6:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I_I_I]], align 1, !tbaa [[TBAA4]]
// APPROX-NEXT: [[CMP_NOT_I_I_I:%.*]] = icmp eq i8 [[TMP6]], 0
// APPROX-NEXT: br i1 [[CMP_NOT_I_I_I]], label [[_ZL4NANFPKC_EXIT]], label [[WHILE_BODY_I_I_I:%.*]]
@@ -2525,30 +2546,33 @@ extern "C" __device__ double test_modf(double x, double* y) {
// APPROX: cleanup.i.i.i:
// APPROX-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
// APPROX-NEXT: [[__R_1_I_I_I]] = phi i64 [ [[SUB_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
+// APPROX-NEXT: [[RETVAL_1_I_I_I]] = phi i64 [ [[RETVAL_0_I_I_I]], [[IF_THEN_I_I_I]] ], [ 0, [[WHILE_BODY_I_I_I]] ]
// APPROX-NEXT: br i1 [[OR_COND_I_I_I]], label [[WHILE_COND_I_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP7]]
// APPROX: while.cond.i14.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I21_I_I:%.*]], [[CLEANUP_I20_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
-// APPROX-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I22_I_I:%.*]], [[CLEANUP_I20_I_I]] ], [ 0, [[ENTRY]] ]
+// APPROX-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I22_I_I:%.*]], [[CLEANUP_I21_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
+// APPROX-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I23_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ 0, [[ENTRY]] ]
+// APPROX-NEXT: [[RETVAL_0_I17_I_I:%.*]] = phi i64 [ [[RETVAL_1_I24_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ undef, [[ENTRY]] ]
// APPROX-NEXT: [[TMP8:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I15_I_I]], align 1, !tbaa [[TBAA4]]
-// APPROX-NEXT: [[CMP_NOT_I17_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
-// APPROX-NEXT: br i1 [[CMP_NOT_I17_I_I]], label [[_ZL4NANFPKC_EXIT]], label [[WHILE_BODY_I18_I_I:%.*]]
-// APPROX: while.body.i18.i.i:
+// APPROX-NEXT: [[CMP_NOT_I18_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
+// APPROX-NEXT: br i1 [[CMP_NOT_I18_I_I]], label [[_ZL4NANFPKC_EXIT]], label [[WHILE_BODY_I19_I_I:%.*]]
+// APPROX: while.body.i19.i.i:
// APPROX-NEXT: [[TMP9:%.*]] = add i8 [[TMP8]], -48
-// APPROX-NEXT: [[OR_COND_I19_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
-// APPROX-NEXT: br i1 [[OR_COND_I19_I_I]], label [[IF_THEN_I24_I_I:%.*]], label [[CLEANUP_I20_I_I]]
-// APPROX: if.then.i24.i.i:
-// APPROX-NEXT: [[MUL_I25_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
-// APPROX-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
-// APPROX-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48
-// APPROX-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]]
-// APPROX-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
-// APPROX-NEXT: br label [[CLEANUP_I20_I_I]]
-// APPROX: cleanup.i20.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// APPROX-NEXT: [[__R_1_I22_I_I]] = phi i64 [ [[SUB_I28_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// APPROX-NEXT: br i1 [[OR_COND_I19_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP10]]
+// APPROX-NEXT: [[OR_COND_I20_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
+// APPROX-NEXT: br i1 [[OR_COND_I20_I_I]], label [[IF_THEN_I26_I_I:%.*]], label [[CLEANUP_I21_I_I]]
+// APPROX: if.then.i26.i.i:
+// APPROX-NEXT: [[MUL_I27_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
+// APPROX-NEXT: [[CONV5_I28_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
+// APPROX-NEXT: [[ADD_I29_I_I:%.*]] = add i64 [[MUL_I27_I_I]], -48
+// APPROX-NEXT: [[SUB_I30_I_I:%.*]] = add i64 [[ADD_I29_I_I]], [[CONV5_I28_I_I]]
+// APPROX-NEXT: [[INCDEC_PTR_I31_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
+// APPROX-NEXT: br label [[CLEANUP_I21_I_I]]
+// APPROX: cleanup.i21.i.i:
+// APPROX-NEXT: [[__TAGP_ADDR_1_I22_I_I]] = phi ptr [ [[INCDEC_PTR_I31_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// APPROX-NEXT: [[__R_1_I23_I_I]] = phi i64 [ [[SUB_I30_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// APPROX-NEXT: [[RETVAL_1_I24_I_I]] = phi i64 [ [[RETVAL_0_I17_I_I]], [[IF_THEN_I26_I_I]] ], [ 0, [[WHILE_BODY_I19_I_I]] ]
+// APPROX-NEXT: br i1 [[OR_COND_I20_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL4NANFPKC_EXIT]], !llvm.loop [[LOOP10]]
// APPROX: _ZL4nanfPKc.exit:
-// APPROX-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ 0, [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ 0, [[CLEANUP_I36_I_I]] ], [ [[__R_0_I32_I_I]], [[WHILE_COND_I30_I_I]] ], [ 0, [[CLEANUP_I20_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
+// APPROX-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I]], [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ [[RETVAL_1_I41_I_I]], [[CLEANUP_I39_I_I]] ], [ [[__R_0_I34_I_I]], [[WHILE_COND_I32_I_I]] ], [ [[RETVAL_1_I24_I_I]], [[CLEANUP_I21_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
// APPROX-NEXT: [[CONV_I:%.*]] = trunc i64 [[RETVAL_0_I_I]] to i32
// APPROX-NEXT: [[BF_VALUE_I:%.*]] = and i32 [[CONV_I]], 4194303
// APPROX-NEXT: [[BF_SET9_I:%.*]] = or disjoint i32 [[BF_VALUE_I]], 2143289344
@@ -2568,21 +2592,22 @@ extern "C" __device__ float test_nanf(const char *tag) {
// DEFAULT-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1
// DEFAULT-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]]
// DEFAULT-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [
-// DEFAULT-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]]
-// DEFAULT-NEXT: i8 88, label [[WHILE_COND_I30_I_I_PREHEADER]]
+// DEFAULT-NEXT: i8 120, label [[WHILE_COND_I32_I_I_PREHEADER:%.*]]
+// DEFAULT-NEXT: i8 88, label [[WHILE_COND_I32_I_I_PREHEADER]]
// DEFAULT-NEXT: ]
-// DEFAULT: while.cond.i30.i.i.preheader:
-// DEFAULT-NEXT: br label [[WHILE_COND_I30_I_I:%.*]]
-// DEFAULT: while.cond.i30.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_0_I31_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I37_I_I:%.*]], [[CLEANUP_I36_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// DEFAULT-NEXT: [[__R_0_I32_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I36_I_I]] ], [ 0, [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// DEFAULT-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I31_I_I]], align 1, !tbaa [[TBAA4]]
-// DEFAULT-NEXT: [[CMP_NOT_I33_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
-// DEFAULT-NEXT: br i1 [[CMP_NOT_I33_I_I]], label [[_ZL3NANPKC_EXIT:%.*]], label [[WHILE_BODY_I34_I_I:%.*]]
-// DEFAULT: while.body.i34.i.i:
+// DEFAULT: while.cond.i32.i.i.preheader:
+// DEFAULT-NEXT: br label [[WHILE_COND_I32_I_I:%.*]]
+// DEFAULT: while.cond.i32.i.i:
+// DEFAULT-NEXT: [[__TAGP_ADDR_0_I33_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I40_I_I:%.*]], [[CLEANUP_I39_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// DEFAULT-NEXT: [[__R_0_I34_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ 0, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I35_I_I:%.*]] = phi i64 [ [[RETVAL_1_I41_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ undef, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// DEFAULT-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I33_I_I]], align 1, !tbaa [[TBAA4]]
+// DEFAULT-NEXT: [[CMP_NOT_I36_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
+// DEFAULT-NEXT: br i1 [[CMP_NOT_I36_I_I]], label [[_ZL3NANPKC_EXIT:%.*]], label [[WHILE_BODY_I37_I_I:%.*]]
+// DEFAULT: while.body.i37.i.i:
// DEFAULT-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], -48
-// DEFAULT-NEXT: [[OR_COND_I35_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
-// DEFAULT-NEXT: br i1 [[OR_COND_I35_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
+// DEFAULT-NEXT: [[OR_COND_I38_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
+// DEFAULT-NEXT: br i1 [[OR_COND_I38_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
// DEFAULT: if.else.i.i.i:
// DEFAULT-NEXT: [[TMP4:%.*]] = add i8 [[TMP2]], -97
// DEFAULT-NEXT: [[OR_COND33_I_I_I:%.*]] = icmp ult i8 [[TMP4]], 6
@@ -2590,23 +2615,25 @@ extern "C" __device__ float test_nanf(const char *tag) {
// DEFAULT: if.else17.i.i.i:
// DEFAULT-NEXT: [[TMP5:%.*]] = add i8 [[TMP2]], -65
// DEFAULT-NEXT: [[OR_COND34_I_I_I:%.*]] = icmp ult i8 [[TMP5]], 6
-// DEFAULT-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I36_I_I]]
+// DEFAULT-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I39_I_I]]
// DEFAULT: if.end31.i.i.i:
-// DEFAULT-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I34_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
-// DEFAULT-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I32_I_I]], 4
+// DEFAULT-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I37_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I34_I_I]], 4
// DEFAULT-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64
// DEFAULT-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]]
// DEFAULT-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]]
-// DEFAULT-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1
-// DEFAULT-NEXT: br label [[CLEANUP_I36_I_I]]
-// DEFAULT: cleanup.i36.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ]
-// DEFAULT-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I32_I_I]], [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[INCDEC_PTR_I44_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I33_I_I]], i64 1
+// DEFAULT-NEXT: br label [[CLEANUP_I39_I_I]]
+// DEFAULT: cleanup.i39.i.i:
+// DEFAULT-NEXT: [[__TAGP_ADDR_1_I40_I_I]] = phi ptr [ [[INCDEC_PTR_I44_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I33_I_I]], [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I34_I_I]], [[IF_ELSE17_I_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_1_I41_I_I]] = phi i64 [ [[RETVAL_0_I35_I_I]], [[IF_END31_I_I_I]] ], [ 0, [[IF_ELSE17_I_I_I]] ]
// DEFAULT-NEXT: [[COND_I_I_I:%.*]] = phi i1 [ true, [[IF_END31_I_I_I]] ], [ false, [[IF_ELSE17_I_I_I]] ]
-// DEFAULT-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I30_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP11]]
+// DEFAULT-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I32_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP11]]
// DEFAULT: while.cond.i.i.i:
// DEFAULT-NEXT: [[__TAGP_ADDR_0_I_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I_I_I:%.*]], [[CLEANUP_I_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[IF_THEN_I_I]] ]
// DEFAULT-NEXT: [[__R_0_I_I_I:%.*]] = phi i64 [ [[__R_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ 0, [[IF_THEN_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ undef, [[IF_THEN_I_I]] ]
// DEFAULT-NEXT: [[TMP6:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I_I_I]], align 1, !tbaa [[TBAA4]]
// DEFAULT-NEXT: [[CMP_NOT_I_I_I:%.*]] = icmp eq i8 [[TMP6]], 0
// DEFAULT-NEXT: br i1 [[CMP_NOT_I_I_I]], label [[_ZL3NANPKC_EXIT]], label [[WHILE_BODY_I_I_I:%.*]]
@@ -2624,30 +2651,33 @@ extern "C" __device__ float test_nanf(const char *tag) {
// DEFAULT: cleanup.i.i.i:
// DEFAULT-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
// DEFAULT-NEXT: [[__R_1_I_I_I]] = phi i64 [ [[SUB_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_1_I_I_I]] = phi i64 [ [[RETVAL_0_I_I_I]], [[IF_THEN_I_I_I]] ], [ 0, [[WHILE_BODY_I_I_I]] ]
// DEFAULT-NEXT: br i1 [[OR_COND_I_I_I]], label [[WHILE_COND_I_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP7]]
// DEFAULT: while.cond.i14.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I21_I_I:%.*]], [[CLEANUP_I20_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
-// DEFAULT-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I22_I_I:%.*]], [[CLEANUP_I20_I_I]] ], [ 0, [[ENTRY]] ]
+// DEFAULT-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I22_I_I:%.*]], [[CLEANUP_I21_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
+// DEFAULT-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I23_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ 0, [[ENTRY]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I17_I_I:%.*]] = phi i64 [ [[RETVAL_1_I24_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ undef, [[ENTRY]] ]
// DEFAULT-NEXT: [[TMP8:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I15_I_I]], align 1, !tbaa [[TBAA4]]
-// DEFAULT-NEXT: [[CMP_NOT_I17_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
-// DEFAULT-NEXT: br i1 [[CMP_NOT_I17_I_I]], label [[_ZL3NANPKC_EXIT]], label [[WHILE_BODY_I18_I_I:%.*]]
-// DEFAULT: while.body.i18.i.i:
+// DEFAULT-NEXT: [[CMP_NOT_I18_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
+// DEFAULT-NEXT: br i1 [[CMP_NOT_I18_I_I]], label [[_ZL3NANPKC_EXIT]], label [[WHILE_BODY_I19_I_I:%.*]]
+// DEFAULT: while.body.i19.i.i:
// DEFAULT-NEXT: [[TMP9:%.*]] = add i8 [[TMP8]], -48
-// DEFAULT-NEXT: [[OR_COND_I19_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
-// DEFAULT-NEXT: br i1 [[OR_COND_I19_I_I]], label [[IF_THEN_I24_I_I:%.*]], label [[CLEANUP_I20_I_I]]
-// DEFAULT: if.then.i24.i.i:
-// DEFAULT-NEXT: [[MUL_I25_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
-// DEFAULT-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
-// DEFAULT-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48
-// DEFAULT-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]]
-// DEFAULT-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
-// DEFAULT-NEXT: br label [[CLEANUP_I20_I_I]]
-// DEFAULT: cleanup.i20.i.i:
-// DEFAULT-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// DEFAULT-NEXT: [[__R_1_I22_I_I]] = phi i64 [ [[SUB_I28_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// DEFAULT-NEXT: br i1 [[OR_COND_I19_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP10]]
+// DEFAULT-NEXT: [[OR_COND_I20_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
+// DEFAULT-NEXT: br i1 [[OR_COND_I20_I_I]], label [[IF_THEN_I26_I_I:%.*]], label [[CLEANUP_I21_I_I]]
+// DEFAULT: if.then.i26.i.i:
+// DEFAULT-NEXT: [[MUL_I27_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
+// DEFAULT-NEXT: [[CONV5_I28_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
+// DEFAULT-NEXT: [[ADD_I29_I_I:%.*]] = add i64 [[MUL_I27_I_I]], -48
+// DEFAULT-NEXT: [[SUB_I30_I_I:%.*]] = add i64 [[ADD_I29_I_I]], [[CONV5_I28_I_I]]
+// DEFAULT-NEXT: [[INCDEC_PTR_I31_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
+// DEFAULT-NEXT: br label [[CLEANUP_I21_I_I]]
+// DEFAULT: cleanup.i21.i.i:
+// DEFAULT-NEXT: [[__TAGP_ADDR_1_I22_I_I]] = phi ptr [ [[INCDEC_PTR_I31_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// DEFAULT-NEXT: [[__R_1_I23_I_I]] = phi i64 [ [[SUB_I30_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_1_I24_I_I]] = phi i64 [ [[RETVAL_0_I17_I_I]], [[IF_THEN_I26_I_I]] ], [ 0, [[WHILE_BODY_I19_I_I]] ]
+// DEFAULT-NEXT: br i1 [[OR_COND_I20_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP10]]
// DEFAULT: _ZL3nanPKc.exit:
-// DEFAULT-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ 0, [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ 0, [[CLEANUP_I36_I_I]] ], [ [[__R_0_I32_I_I]], [[WHILE_COND_I30_I_I]] ], [ 0, [[CLEANUP_I20_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
+// DEFAULT-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I]], [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ [[RETVAL_1_I41_I_I]], [[CLEANUP_I39_I_I]] ], [ [[__R_0_I34_I_I]], [[WHILE_COND_I32_I_I]] ], [ [[RETVAL_1_I24_I_I]], [[CLEANUP_I21_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
// DEFAULT-NEXT: [[BF_VALUE_I:%.*]] = and i64 [[RETVAL_0_I_I]], 2251799813685247
// DEFAULT-NEXT: [[BF_SET9_I:%.*]] = or disjoint i64 [[BF_VALUE_I]], 9221120237041090560
// DEFAULT-NEXT: [[TMP10:%.*]] = bitcast i64 [[BF_SET9_I]] to double
@@ -2666,21 +2696,22 @@ extern "C" __device__ float test_nanf(const char *tag) {
// APPROX-NEXT: [[INCDEC_PTR_I_I:%.*]] = getelementptr inbounds i8, ptr [[TAG]], i64 1
// APPROX-NEXT: [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR_I_I]], align 1, !tbaa [[TBAA4]]
// APPROX-NEXT: switch i8 [[TMP1]], label [[WHILE_COND_I_I_I:%.*]] [
-// APPROX-NEXT: i8 120, label [[WHILE_COND_I30_I_I_PREHEADER:%.*]]
-// APPROX-NEXT: i8 88, label [[WHILE_COND_I30_I_I_PREHEADER]]
+// APPROX-NEXT: i8 120, label [[WHILE_COND_I32_I_I_PREHEADER:%.*]]
+// APPROX-NEXT: i8 88, label [[WHILE_COND_I32_I_I_PREHEADER]]
// APPROX-NEXT: ]
-// APPROX: while.cond.i30.i.i.preheader:
-// APPROX-NEXT: br label [[WHILE_COND_I30_I_I:%.*]]
-// APPROX: while.cond.i30.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_0_I31_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I37_I_I:%.*]], [[CLEANUP_I36_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// APPROX-NEXT: [[__R_0_I32_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I36_I_I]] ], [ 0, [[WHILE_COND_I30_I_I_PREHEADER]] ]
-// APPROX-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I31_I_I]], align 1, !tbaa [[TBAA4]]
-// APPROX-NEXT: [[CMP_NOT_I33_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
-// APPROX-NEXT: br i1 [[CMP_NOT_I33_I_I]], label [[_ZL3NANPKC_EXIT:%.*]], label [[WHILE_BODY_I34_I_I:%.*]]
-// APPROX: while.body.i34.i.i:
+// APPROX: while.cond.i32.i.i.preheader:
+// APPROX-NEXT: br label [[WHILE_COND_I32_I_I:%.*]]
+// APPROX: while.cond.i32.i.i:
+// APPROX-NEXT: [[__TAGP_ADDR_0_I33_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I40_I_I:%.*]], [[CLEANUP_I39_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// APPROX-NEXT: [[__R_0_I34_I_I:%.*]] = phi i64 [ [[__R_2_I_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ 0, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// APPROX-NEXT: [[RETVAL_0_I35_I_I:%.*]] = phi i64 [ [[RETVAL_1_I41_I_I:%.*]], [[CLEANUP_I39_I_I]] ], [ undef, [[WHILE_COND_I32_I_I_PREHEADER]] ]
+// APPROX-NEXT: [[TMP2:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I33_I_I]], align 1, !tbaa [[TBAA4]]
+// APPROX-NEXT: [[CMP_NOT_I36_I_I:%.*]] = icmp eq i8 [[TMP2]], 0
+// APPROX-NEXT: br i1 [[CMP_NOT_I36_I_I]], label [[_ZL3NANPKC_EXIT:%.*]], label [[WHILE_BODY_I37_I_I:%.*]]
+// APPROX: while.body.i37.i.i:
// APPROX-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], -48
-// APPROX-NEXT: [[OR_COND_I35_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
-// APPROX-NEXT: br i1 [[OR_COND_I35_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
+// APPROX-NEXT: [[OR_COND_I38_I_I:%.*]] = icmp ult i8 [[TMP3]], 10
+// APPROX-NEXT: br i1 [[OR_COND_I38_I_I]], label [[IF_END31_I_I_I:%.*]], label [[IF_ELSE_I_I_I:%.*]]
// APPROX: if.else.i.i.i:
// APPROX-NEXT: [[TMP4:%.*]] = add i8 [[TMP2]], -97
// APPROX-NEXT: [[OR_COND33_I_I_I:%.*]] = icmp ult i8 [[TMP4]], 6
@@ -2688,23 +2719,25 @@ extern "C" __device__ float test_nanf(const char *tag) {
// APPROX: if.else17.i.i.i:
// APPROX-NEXT: [[TMP5:%.*]] = add i8 [[TMP2]], -65
// APPROX-NEXT: [[OR_COND34_I_I_I:%.*]] = icmp ult i8 [[TMP5]], 6
-// APPROX-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I36_I_I]]
+// APPROX-NEXT: br i1 [[OR_COND34_I_I_I]], label [[IF_END31_I_I_I]], label [[CLEANUP_I39_I_I]]
// APPROX: if.end31.i.i.i:
-// APPROX-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I34_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
-// APPROX-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I32_I_I]], 4
+// APPROX-NEXT: [[DOTSINK:%.*]] = phi i64 [ -48, [[WHILE_BODY_I37_I_I]] ], [ -87, [[IF_ELSE_I_I_I]] ], [ -55, [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[MUL24_I_I_I:%.*]] = shl i64 [[__R_0_I34_I_I]], 4
// APPROX-NEXT: [[CONV25_I_I_I:%.*]] = zext nneg i8 [[TMP2]] to i64
// APPROX-NEXT: [[ADD26_I_I_I:%.*]] = add i64 [[MUL24_I_I_I]], [[DOTSINK]]
// APPROX-NEXT: [[ADD28_I_I_I:%.*]] = add i64 [[ADD26_I_I_I]], [[CONV25_I_I_I]]
-// APPROX-NEXT: [[INCDEC_PTR_I40_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I31_I_I]], i64 1
-// APPROX-NEXT: br label [[CLEANUP_I36_I_I]]
-// APPROX: cleanup.i36.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_1_I37_I_I]] = phi ptr [ [[INCDEC_PTR_I40_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I31_I_I]], [[IF_ELSE17_I_I_I]] ]
-// APPROX-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I32_I_I]], [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[INCDEC_PTR_I44_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I33_I_I]], i64 1
+// APPROX-NEXT: br label [[CLEANUP_I39_I_I]]
+// APPROX: cleanup.i39.i.i:
+// APPROX-NEXT: [[__TAGP_ADDR_1_I40_I_I]] = phi ptr [ [[INCDEC_PTR_I44_I_I]], [[IF_END31_I_I_I]] ], [ [[__TAGP_ADDR_0_I33_I_I]], [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[__R_2_I_I_I]] = phi i64 [ [[ADD28_I_I_I]], [[IF_END31_I_I_I]] ], [ [[__R_0_I34_I_I]], [[IF_ELSE17_I_I_I]] ]
+// APPROX-NEXT: [[RETVAL_1_I41_I_I]] = phi i64 [ [[RETVAL_0_I35_I_I]], [[IF_END31_I_I_I]] ], [ 0, [[IF_ELSE17_I_I_I]] ]
// APPROX-NEXT: [[COND_I_I_I:%.*]] = phi i1 [ true, [[IF_END31_I_I_I]] ], [ false, [[IF_ELSE17_I_I_I]] ]
-// APPROX-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I30_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP11]]
+// APPROX-NEXT: br i1 [[COND_I_I_I]], label [[WHILE_COND_I32_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP11]]
// APPROX: while.cond.i.i.i:
// APPROX-NEXT: [[__TAGP_ADDR_0_I_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I_I_I:%.*]], [[CLEANUP_I_I_I:%.*]] ], [ [[INCDEC_PTR_I_I]], [[IF_THEN_I_I]] ]
// APPROX-NEXT: [[__R_0_I_I_I:%.*]] = phi i64 [ [[__R_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ 0, [[IF_THEN_I_I]] ]
+// APPROX-NEXT: [[RETVAL_0_I_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I:%.*]], [[CLEANUP_I_I_I]] ], [ undef, [[IF_THEN_I_I]] ]
// APPROX-NEXT: [[TMP6:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I_I_I]], align 1, !tbaa [[TBAA4]]
// APPROX-NEXT: [[CMP_NOT_I_I_I:%.*]] = icmp eq i8 [[TMP6]], 0
// APPROX-NEXT: br i1 [[CMP_NOT_I_I_I]], label [[_ZL3NANPKC_EXIT]], label [[WHILE_BODY_I_I_I:%.*]]
@@ -2722,30 +2755,33 @@ extern "C" __device__ float test_nanf(const char *tag) {
// APPROX: cleanup.i.i.i:
// APPROX-NEXT: [[__TAGP_ADDR_1_I_I_I]] = phi ptr [ [[INCDEC_PTR_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__TAGP_ADDR_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
// APPROX-NEXT: [[__R_1_I_I_I]] = phi i64 [ [[SUB_I_I_I]], [[IF_THEN_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_BODY_I_I_I]] ]
+// APPROX-NEXT: [[RETVAL_1_I_I_I]] = phi i64 [ [[RETVAL_0_I_I_I]], [[IF_THEN_I_I_I]] ], [ 0, [[WHILE_BODY_I_I_I]] ]
// APPROX-NEXT: br i1 [[OR_COND_I_I_I]], label [[WHILE_COND_I_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP7]]
// APPROX: while.cond.i14.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I21_I_I:%.*]], [[CLEANUP_I20_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
-// APPROX-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I22_I_I:%.*]], [[CLEANUP_I20_I_I]] ], [ 0, [[ENTRY]] ]
+// APPROX-NEXT: [[__TAGP_ADDR_0_I15_I_I:%.*]] = phi ptr [ [[__TAGP_ADDR_1_I22_I_I:%.*]], [[CLEANUP_I21_I_I:%.*]] ], [ [[TAG]], [[ENTRY:%.*]] ]
+// APPROX-NEXT: [[__R_0_I16_I_I:%.*]] = phi i64 [ [[__R_1_I23_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ 0, [[ENTRY]] ]
+// APPROX-NEXT: [[RETVAL_0_I17_I_I:%.*]] = phi i64 [ [[RETVAL_1_I24_I_I:%.*]], [[CLEANUP_I21_I_I]] ], [ undef, [[ENTRY]] ]
// APPROX-NEXT: [[TMP8:%.*]] = load i8, ptr [[__TAGP_ADDR_0_I15_I_I]], align 1, !tbaa [[TBAA4]]
-// APPROX-NEXT: [[CMP_NOT_I17_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
-// APPROX-NEXT: br i1 [[CMP_NOT_I17_I_I]], label [[_ZL3NANPKC_EXIT]], label [[WHILE_BODY_I18_I_I:%.*]]
-// APPROX: while.body.i18.i.i:
+// APPROX-NEXT: [[CMP_NOT_I18_I_I:%.*]] = icmp eq i8 [[TMP8]], 0
+// APPROX-NEXT: br i1 [[CMP_NOT_I18_I_I]], label [[_ZL3NANPKC_EXIT]], label [[WHILE_BODY_I19_I_I:%.*]]
+// APPROX: while.body.i19.i.i:
// APPROX-NEXT: [[TMP9:%.*]] = add i8 [[TMP8]], -48
-// APPROX-NEXT: [[OR_COND_I19_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
-// APPROX-NEXT: br i1 [[OR_COND_I19_I_I]], label [[IF_THEN_I24_I_I:%.*]], label [[CLEANUP_I20_I_I]]
-// APPROX: if.then.i24.i.i:
-// APPROX-NEXT: [[MUL_I25_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
-// APPROX-NEXT: [[CONV5_I26_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
-// APPROX-NEXT: [[ADD_I27_I_I:%.*]] = add i64 [[MUL_I25_I_I]], -48
-// APPROX-NEXT: [[SUB_I28_I_I:%.*]] = add i64 [[ADD_I27_I_I]], [[CONV5_I26_I_I]]
-// APPROX-NEXT: [[INCDEC_PTR_I29_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
-// APPROX-NEXT: br label [[CLEANUP_I20_I_I]]
-// APPROX: cleanup.i20.i.i:
-// APPROX-NEXT: [[__TAGP_ADDR_1_I21_I_I]] = phi ptr [ [[INCDEC_PTR_I29_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// APPROX-NEXT: [[__R_1_I22_I_I]] = phi i64 [ [[SUB_I28_I_I]], [[IF_THEN_I24_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I18_I_I]] ]
-// APPROX-NEXT: br i1 [[OR_COND_I19_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP10]]
+// APPROX-NEXT: [[OR_COND_I20_I_I:%.*]] = icmp ult i8 [[TMP9]], 10
+// APPROX-NEXT: br i1 [[OR_COND_I20_I_I]], label [[IF_THEN_I26_I_I:%.*]], label [[CLEANUP_I21_I_I]]
+// APPROX: if.then.i26.i.i:
+// APPROX-NEXT: [[MUL_I27_I_I:%.*]] = mul i64 [[__R_0_I16_I_I]], 10
+// APPROX-NEXT: [[CONV5_I28_I_I:%.*]] = zext nneg i8 [[TMP8]] to i64
+// APPROX-NEXT: [[ADD_I29_I_I:%.*]] = add i64 [[MUL_I27_I_I]], -48
+// APPROX-NEXT: [[SUB_I30_I_I:%.*]] = add i64 [[ADD_I29_I_I]], [[CONV5_I28_I_I]]
+// APPROX-NEXT: [[INCDEC_PTR_I31_I_I:%.*]] = getelementptr inbounds i8, ptr [[__TAGP_ADDR_0_I15_I_I]], i64 1
+// APPROX-NEXT: br label [[CLEANUP_I21_I_I]]
+// APPROX: cleanup.i21.i.i:
+// APPROX-NEXT: [[__TAGP_ADDR_1_I22_I_I]] = phi ptr [ [[INCDEC_PTR_I31_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__TAGP_ADDR_0_I15_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// APPROX-NEXT: [[__R_1_I23_I_I]] = phi i64 [ [[SUB_I30_I_I]], [[IF_THEN_I26_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_BODY_I19_I_I]] ]
+// APPROX-NEXT: [[RETVAL_1_I24_I_I]] = phi i64 [ [[RETVAL_0_I17_I_I]], [[IF_THEN_I26_I_I]] ], [ 0, [[WHILE_BODY_I19_I_I]] ]
+// APPROX-NEXT: br i1 [[OR_COND_I20_I_I]], label [[WHILE_COND_I14_I_I]], label [[_ZL3NANPKC_EXIT]], !llvm.loop [[LOOP10]]
// APPROX: _ZL3nanPKc.exit:
-// APPROX-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ 0, [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ 0, [[CLEANUP_I36_I_I]] ], [ [[__R_0_I32_I_I]], [[WHILE_COND_I30_I_I]] ], [ 0, [[CLEANUP_I20_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
+// APPROX-NEXT: [[RETVAL_0_I_I:%.*]] = phi i64 [ [[RETVAL_1_I_I_I]], [[CLEANUP_I_I_I]] ], [ [[__R_0_I_I_I]], [[WHILE_COND_I_I_I]] ], [ [[RETVAL_1_I41_I_I]], [[CLEANUP_I39_I_I]] ], [ [[__R_0_I34_I_I]], [[WHILE_COND_I32_I_I]] ], [ [[RETVAL_1_I24_I_I]], [[CLEANUP_I21_I_I]] ], [ [[__R_0_I16_I_I]], [[WHILE_COND_I14_I_I]] ]
// APPROX-NEXT: [[BF_VALUE_I:%.*]] = and i64 [[RETVAL_0_I_I]], 2251799813685247
// APPROX-NEXT: [[BF_SET9_I:%.*]] = or disjoint i64 [[BF_VALUE_I]], 9221120237041090560
// APPROX-NEXT: [[TMP10:%.*]] = bitcast i64 [[BF_SET9_I]] to double
diff --git a/llvm/include/llvm/Analysis/ValueLattice.h b/llvm/include/llvm/Analysis/ValueLattice.h
index 9357a15f7619f1..51e91dba24bb41 100644
--- a/llvm/include/llvm/Analysis/ValueLattice.h
+++ b/llvm/include/llvm/Analysis/ValueLattice.h
@@ -32,19 +32,9 @@ class ValueLatticeElement {
/// Transition to any other state allowed.
unknown,
- /// This Value is an UndefValue constant or produces undef. Undefined values
- /// can be merged with constants (or single element constant ranges),
- /// assuming all uses of the result will be replaced.
- /// Transition allowed to the following states:
- /// constant
- /// constantrange_including_undef
- /// overdefined
- undef,
-
- /// This Value has a specific constant value. The constant cannot be undef.
+ /// This Value has a specific constant value.
/// (For constant integers, constantrange is used instead. Integer typed
- /// constantexprs can appear as constant.) Note that the constant state
- /// can be reached by merging undef & constant states.
+ /// constantexprs can appear as constant.)
/// Transition allowed to the following states:
/// overdefined
constant,
@@ -92,7 +82,6 @@ class ValueLatticeElement {
switch (Tag) {
case overdefined:
case unknown:
- case undef:
case constant:
case notconstant:
break;
@@ -160,7 +149,6 @@ class ValueLatticeElement {
break;
case overdefined:
case unknown:
- case undef:
break;
}
}
@@ -179,7 +167,6 @@ class ValueLatticeElement {
break;
case overdefined:
case unknown:
- case undef:
break;
}
Other.Tag = unknown;
@@ -213,12 +200,8 @@ class ValueLatticeElement {
if (CR.isFullSet())
return getOverdefined();
- if (CR.isEmptySet()) {
- ValueLatticeElement Res;
- if (MayIncludeUndef)
- Res.markUndef();
- return Res;
- }
+ if (CR.isEmptySet())
+ return ValueLatticeElement();
ValueLatticeElement Res;
Res.markConstantRange(std::move(CR),
@@ -231,11 +214,12 @@ class ValueLatticeElement {
return Res;
}
- bool isUndef() const { return Tag == undef; }
bool isUnknown() const { return Tag == unknown; }
- bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; }
bool isConstant() const { return Tag == constant; }
bool isNotConstant() const { return Tag == notconstant; }
+ bool isUndefConstant() const {
+ return Tag == constant && isa<UndefValue>(ConstVal);
+ }
bool isConstantRangeIncludingUndef() const {
return Tag == constantrange_including_undef;
}
@@ -301,18 +285,12 @@ class ValueLatticeElement {
return true;
}
- bool markUndef() {
- if (isUndef())
- return false;
-
- assert(isUnknown());
- Tag = undef;
- return true;
- }
-
bool markConstant(Constant *V, bool MayIncludeUndef = false) {
- if (isa<UndefValue>(V))
- return markUndef();
+ if (isa<PoisonValue>(V)) {
+ // TODO: Make this a separate state.
+ assert(isUnknown());
+ return false;
+ }
if (isConstant()) {
assert(getConstant() == V && "Marking constant with different value");
@@ -324,7 +302,7 @@ class ValueLatticeElement {
ConstantRange(CI->getValue()),
MergeOptions().setMayIncludeUndef(MayIncludeUndef));
- assert(isUnknown() || isUndef());
+ assert(isUnknown());
Tag = constant;
ConstVal = V;
return true;
@@ -365,7 +343,7 @@ class ValueLatticeElement {
ValueLatticeElementTy OldTag = Tag;
ValueLatticeElementTy NewTag =
- (isUndef() || isConstantRangeIncludingUndef() || Opts.MayIncludeUndef)
+ (isConstantRangeIncludingUndef() || Opts.MayIncludeUndef)
? constantrange_including_undef
: constantrange;
if (isConstantRange()) {
@@ -384,7 +362,7 @@ class ValueLatticeElement {
return true;
}
- assert(isUnknown() || isUndef() || isConstant());
+ assert(isUnknown() || isConstant());
assert((!isConstant() || NewR.contains(getConstant()->toConstantRange())) &&
"Constant must be subset of new range");
@@ -405,18 +383,6 @@ class ValueLatticeElement {
return true;
}
- if (isUndef()) {
- assert(!RHS.isUnknown());
- if (RHS.isUndef())
- return false;
- if (RHS.isConstant())
- return markConstant(RHS.getConstant(), true);
- if (RHS.isConstantRange())
- return markConstantRange(RHS.getConstantRange(true),
- Opts.setMayIncludeUndef());
- return markOverdefined();
- }
-
if (isUnknown()) {
assert(!RHS.isUnknown() && "Unknow RHS should be handled earlier");
*this = RHS;
@@ -426,8 +392,6 @@ class ValueLatticeElement {
if (isConstant()) {
if (RHS.isConstant() && getConstant() == RHS.getConstant())
return false;
- if (RHS.isUndef())
- return false;
// If the constant is a vector of integers, try to treat it as a range.
if (getConstant()->getType()->isVectorTy() &&
getConstant()->getType()->getScalarType()->isIntegerTy()) {
@@ -449,12 +413,7 @@ class ValueLatticeElement {
return true;
}
- auto OldTag = Tag;
assert(isConstantRange() && "New ValueLattice type?");
- if (RHS.isUndef()) {
- Tag = constantrange_including_undef;
- return OldTag != Tag;
- }
const ConstantRange &L = getConstantRange();
ConstantRange NewR = L.unionWith(
diff --git a/llvm/include/llvm/Transforms/Utils/SCCPSolver.h b/llvm/include/llvm/Transforms/Utils/SCCPSolver.h
index 61a500b82875fb..72f8a13ef7cf86 100644
--- a/llvm/include/llvm/Transforms/Utils/SCCPSolver.h
+++ b/llvm/include/llvm/Transforms/Utils/SCCPSolver.h
@@ -107,19 +107,6 @@ class SCCPSolver {
/// Solve - Solve for constants and executable blocks.
void solve();
- /// resolvedUndefsIn - While solving the dataflow for a function, we assume
- /// that branches on undef values cannot reach any of their successors.
- /// However, this is not a safe assumption. After we solve dataflow, this
- /// method should be use to handle this. If this returns true, the solver
- /// should be rerun.
- bool resolvedUndefsIn(Function &F);
-
- void solveWhileResolvedUndefsIn(Module &M);
-
- void solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList);
-
- void solveWhileResolvedUndefs();
-
bool isBlockExecutable(BasicBlock *BB) const;
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
@@ -134,6 +121,10 @@ class SCCPSolver {
/// the call. Then recompute it.
void resetLatticeValueFor(CallBase *Call);
+ /// Reset set of invalidated values after all calls to resetLatticeValueFor()
+ /// are done.
+ void resetInvalidated();
+
const ValueLatticeElement &getLatticeValueFor(Value *V) const;
/// getTrackedRetVals - Get the inferred return value map.
diff --git a/llvm/lib/Analysis/ValueLattice.cpp b/llvm/lib/Analysis/ValueLattice.cpp
index 03810f1c554e5d..d880a8f20667d2 100644
--- a/llvm/lib/Analysis/ValueLattice.cpp
+++ b/llvm/lib/Analysis/ValueLattice.cpp
@@ -19,11 +19,6 @@ ValueLatticeElement::getCompare(CmpInst::Predicate Pred, Type *Ty,
if (isUnknown() || Other.isUnknown())
return nullptr;
- // TODO: Can be made more precise, but always returning undef would be
- // incorrect.
- if (isUndef() || Other.isUndef())
- return nullptr;
-
if (isConstant() && Other.isConstant())
return ConstantFoldCompareInstOperands(Pred, getConstant(),
Other.getConstant(), DL);
@@ -112,8 +107,6 @@ ValueLatticeElement::intersect(const ValueLatticeElement &Other) const {
raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val) {
if (Val.isUnknown())
return OS << "unknown";
- if (Val.isUndef())
- return OS << "undef";
if (Val.isOverdefined())
return OS << "overdefined";
diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 548335d750e33d..69772b31b4f8de 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -736,7 +736,7 @@ bool FunctionSpecializer::run() {
OriginalFuncs.insert(S.F);
}
- Solver.solveWhileResolvedUndefsIn(Clones);
+ Solver.solve();
// Update the rest of the call sites - these are the recursive calls, calls
// to discarded specialisations and calls that may match a specialisation
@@ -771,7 +771,8 @@ bool FunctionSpecializer::run() {
}
// Rerun the solver to notify the users of the modified callsites.
- Solver.solveWhileResolvedUndefs();
+ Solver.resetInvalidated();
+ Solver.solve();
for (Function *F : OriginalFuncs)
if (FunctionMetrics[F].isRecursive)
diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp
index f0d75a2016363a..cedd81cd803cfe 100644
--- a/llvm/lib/Transforms/IPO/SCCP.cpp
+++ b/llvm/lib/Transforms/IPO/SCCP.cpp
@@ -158,7 +158,7 @@ static bool runIPSCCP(
}
// Solve for constants.
- Solver.solveWhileResolvedUndefsIn(M);
+ Solver.solve();
if (IsFuncSpecEnabled) {
unsigned Iters = 0;
@@ -281,7 +281,7 @@ static bool runIPSCCP(
for (const auto &[F, ReturnValue] : Solver.getTrackedRetVals()) {
assert(!F->getReturnType()->isVoidTy() &&
"should not track void functions");
- if (SCCPSolver::isConstant(ReturnValue) || ReturnValue.isUnknownOrUndef())
+ if (SCCPSolver::isConstant(ReturnValue) || ReturnValue.isUnknown())
findReturnsToZap(*F, ReturnsToZap, Solver);
}
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index 0330460e7df8ab..8646848f1b8a0f 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -80,12 +80,7 @@ static bool runSCCP(Function &F, const DataLayout &DL,
Solver.trackValueOfArgument(&AI);
// Solve for constants.
- bool ResolvedUndefs = true;
- while (ResolvedUndefs) {
- Solver.solve();
- LLVM_DEBUG(dbgs() << "RESOLVING UNDEFs\n");
- ResolvedUndefs = Solver.resolvedUndefsIn(F);
- }
+ Solver.solve();
bool MadeChanges = false;
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 1dc82c6e9aa716..50f1e3f1e40030 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -51,7 +51,7 @@ bool SCCPSolver::isConstant(const ValueLatticeElement &LV) {
}
bool SCCPSolver::isOverdefined(const ValueLatticeElement &LV) {
- return !LV.isUnknownOrUndef() && !SCCPSolver::isConstant(LV);
+ return !LV.isUnknown() && !SCCPSolver::isConstant(LV);
}
static bool canRemoveInstruction(Instruction *I) {
@@ -412,7 +412,7 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
TrackedMultipleRetVals;
/// The set of values whose lattice has been invalidated.
- /// Populated by resetLatticeValueFor(), cleared after resolving undefs.
+ /// Populated by resetLatticeValueFor(), cleared by resetInvalidated().
DenseSet<Value *> Invalidated;
/// MRVFunctionsTracked - Each function in TrackedMultipleRetVals is
@@ -781,10 +781,6 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
void solve();
- bool resolvedUndef(Instruction &I);
-
- bool resolvedUndefsIn(Function &F);
-
bool isBlockExecutable(BasicBlock *BB) const {
return BBExecutable.count(BB);
}
@@ -818,6 +814,10 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
handleCallResult(*Call);
}
+ void resetInvalidated() {
+ Invalidated.clear();
+ }
+
const ValueLatticeElement &getLatticeValueFor(Value *V) const {
assert(!V->getType()->isStructTy() &&
"Should use getStructLatticeValueFor");
@@ -878,38 +878,6 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
for (auto &BB : *F)
BBExecutable.erase(&BB);
}
-
- void solveWhileResolvedUndefsIn(Module &M) {
- bool ResolvedUndefs = true;
- while (ResolvedUndefs) {
- solve();
- ResolvedUndefs = false;
- for (Function &F : M)
- ResolvedUndefs |= resolvedUndefsIn(F);
- }
- }
-
- void solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList) {
- bool ResolvedUndefs = true;
- while (ResolvedUndefs) {
- solve();
- ResolvedUndefs = false;
- for (Function *F : WorkList)
- ResolvedUndefs |= resolvedUndefsIn(*F);
- }
- }
-
- void solveWhileResolvedUndefs() {
- bool ResolvedUndefs = true;
- while (ResolvedUndefs) {
- solve();
- ResolvedUndefs = false;
- for (Value *V : Invalidated)
- if (auto *I = dyn_cast<Instruction>(V))
- ResolvedUndefs |= resolvedUndef(*I);
- }
- Invalidated.clear();
- }
};
} // namespace llvm
@@ -1016,7 +984,7 @@ Constant *SCCPInstVisitor::getConstantOrNull(Value *V) const {
ValueLatticeElement LV = LVs[I];
ConstVals.push_back(SCCPSolver::isConstant(LV)
? getConstant(LV, ST->getElementType(I))
- : UndefValue::get(ST->getElementType(I)));
+ : PoisonValue::get(ST->getElementType(I)));
}
Const = ConstantStruct::get(ST, ConstVals);
} else {
@@ -1024,7 +992,7 @@ Constant *SCCPInstVisitor::getConstantOrNull(Value *V) const {
if (SCCPSolver::isOverdefined(LV))
return nullptr;
Const = SCCPSolver::isConstant(LV) ? getConstant(LV, V->getType())
- : UndefValue::get(V->getType());
+ : PoisonValue::get(V->getType());
}
assert(Const && "Constant is nullptr here!");
return Const;
@@ -1118,11 +1086,14 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
}
ValueLatticeElement BCValue = getValueState(BI->getCondition());
+ if (isa_and_nonnull<UndefValue>(
+ getConstant(BCValue, BI->getCondition()->getType())))
+ return;
ConstantInt *CI = getConstantInt(BCValue, BI->getCondition()->getType());
if (!CI) {
// Overdefined condition variables, and branches on unfoldable constant
// conditions, mean the branch could go either way.
- if (!BCValue.isUnknownOrUndef())
+ if (!BCValue.isUnknown() && !BCValue.isUndefConstant())
Succs[0] = Succs[1] = true;
return;
}
@@ -1145,6 +1116,9 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
return;
}
const ValueLatticeElement &SCValue = getValueState(SI->getCondition());
+ if (isa_and_nonnull<UndefValue>(
+ getConstant(SCValue, SI->getCondition()->getType())))
+ return;
if (ConstantInt *CI =
getConstantInt(SCValue, SI->getCondition()->getType())) {
Succs[SI->findCaseValue(CI)->getSuccessorIndex()] = true;
@@ -1170,7 +1144,7 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
}
// Overdefined or unknown condition? All destinations are executable!
- if (!SCValue.isUnknownOrUndef())
+ if (!SCValue.isUnknown() && !SCValue.isUndefConstant())
Succs.assign(TI.getNumSuccessors(), true);
return;
}
@@ -1180,11 +1154,14 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
if (auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
// Casts are folded by visitCastInst.
ValueLatticeElement IBRValue = getValueState(IBR->getAddress());
+ if (isa_and_nonnull<UndefValue>(
+ getConstant(IBRValue, IBR->getAddress()->getType())))
+ return;
BlockAddress *Addr = dyn_cast_or_null<BlockAddress>(
getConstant(IBRValue, IBR->getAddress()->getType()));
if (!Addr) { // Overdefined or unknown condition?
// All destinations are executable!
- if (!IBRValue.isUnknownOrUndef())
+ if (!IBRValue.isUnknown() && !IBRValue.isUndefConstant())
Succs.assign(TI.getNumSuccessors(), true);
return;
}
@@ -1326,7 +1303,7 @@ void SCCPInstVisitor::visitCastInst(CastInst &I) {
return;
ValueLatticeElement OpSt = getValueState(I.getOperand(0));
- if (OpSt.isUnknownOrUndef())
+ if (OpSt.isUnknown())
return;
if (Constant *OpC = getConstant(OpSt, I.getOperand(0)->getType())) {
@@ -1360,7 +1337,7 @@ void SCCPInstVisitor::handleExtractOfWithOverflow(ExtractValueInst &EVI,
ValueLatticeElement R = getValueState(RHS);
addAdditionalUser(LHS, &EVI);
addAdditionalUser(RHS, &EVI);
- if (L.isUnknownOrUndef() || R.isUnknownOrUndef())
+ if (L.isUnknown() || R.isUnknown())
return; // Wait to resolve.
Type *Ty = LHS->getType();
@@ -1385,11 +1362,6 @@ void SCCPInstVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
if (EVI.getType()->isStructTy())
return (void)markOverdefined(&EVI);
- // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
- // discover a concrete value later.
- if (ValueState[&EVI].isOverdefined())
- return (void)markOverdefined(&EVI);
-
// If this is extracting from more than one level of struct, we don't know.
if (EVI.getNumIndices() != 1)
return (void)markOverdefined(&EVI);
@@ -1412,11 +1384,6 @@ void SCCPInstVisitor::visitInsertValueInst(InsertValueInst &IVI) {
if (!STy)
return (void)markOverdefined(&IVI);
- // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
- // discover a concrete value later.
- if (ValueState[&IVI].isOverdefined())
- return (void)markOverdefined(&IVI);
-
// If this has more than one index, we can't handle it, drive all results to
// undef.
if (IVI.getNumIndices() != 1)
@@ -1451,13 +1418,8 @@ void SCCPInstVisitor::visitSelectInst(SelectInst &I) {
if (I.getType()->isStructTy())
return (void)markOverdefined(&I);
- // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
- // discover a concrete value later.
- if (ValueState[&I].isOverdefined())
- return (void)markOverdefined(&I);
-
ValueLatticeElement CondValue = getValueState(I.getCondition());
- if (CondValue.isUnknownOrUndef())
+ if (CondValue.isUnknown())
return;
if (ConstantInt *CondCB =
@@ -1484,13 +1446,9 @@ void SCCPInstVisitor::visitUnaryOperator(Instruction &I) {
ValueLatticeElement V0State = getValueState(I.getOperand(0));
ValueLatticeElement &IV = ValueState[&I];
- // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
- // discover a concrete value later.
- if (IV.isOverdefined())
- return (void)markOverdefined(&I);
- // If something is unknown/undef, wait for it to resolve.
- if (V0State.isUnknownOrUndef())
+ // If something is unknown, wait for it to resolve.
+ if (V0State.isUnknown())
return;
if (SCCPSolver::isConstant(V0State))
@@ -1509,13 +1467,9 @@ void SCCPInstVisitor::visitFreezeInst(FreezeInst &I) {
ValueLatticeElement V0State = getValueState(I.getOperand(0));
ValueLatticeElement &IV = ValueState[&I];
- // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
- // discover a concrete value later.
- if (IV.isOverdefined())
- return (void)markOverdefined(&I);
- // If something is unknown/undef, wait for it to resolve.
- if (V0State.isUnknownOrUndef())
+ // If something is unknown, wait for it to resolve.
+ if (V0State.isUnknown())
return;
if (SCCPSolver::isConstant(V0State) &&
@@ -1534,8 +1488,8 @@ void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
if (IV.isOverdefined())
return;
- // If something is undef, wait for it to resolve.
- if (V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef())
+ // If something is unknown, wait for it to resolve.
+ if (V1State.isUnknown() || V2State.isUnknown())
return;
if (V1State.isOverdefined() && V2State.isOverdefined())
@@ -1611,7 +1565,7 @@ void SCCPInstVisitor::visitCmpInst(CmpInst &I) {
}
// If operands are still unknown, wait for it to resolve.
- if ((V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef()) &&
+ if ((V1State.isUnknown() || V2State.isUnknown()) &&
!SCCPSolver::isConstant(ValueState[&I]))
return;
@@ -1625,7 +1579,7 @@ void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
return (void)markOverdefined(&I);
const ValueLatticeElement &PtrState = getValueState(I.getPointerOperand());
- if (PtrState.isUnknownOrUndef())
+ if (PtrState.isUnknown())
return;
// gep inbounds/nuw of non-null is non-null.
@@ -1642,7 +1596,7 @@ void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
ValueLatticeElement State = getValueState(I.getOperand(i));
- if (State.isUnknownOrUndef())
+ if (State.isUnknown())
return; // Operands are not resolved yet.
if (Constant *C = getConstant(State, I.getOperand(i)->getType())) {
@@ -1715,13 +1669,8 @@ void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
if (I.getType()->isStructTy() || I.isVolatile())
return (void)markOverdefined(&I);
- // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
- // discover a concrete value later.
- if (ValueState[&I].isOverdefined())
- return (void)markOverdefined(&I);
-
ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
- if (PtrVal.isUnknownOrUndef())
+ if (PtrVal.isUnknown())
return; // The pointer is not resolved yet!
ValueLatticeElement &IV = ValueState[&I];
@@ -1736,6 +1685,9 @@ void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
else
return;
}
+ // load undef is undefined (even if null pointer is defined).
+ if (isa<UndefValue>(Ptr))
+ return;
// Transform load (constant global) into the value loaded.
if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
@@ -1785,7 +1737,7 @@ void SCCPInstVisitor::handleCallOverdefined(CallBase &CB) {
continue; // Carried in CB, not allowed in Operands.
ValueLatticeElement State = getValueState(A);
- if (State.isUnknownOrUndef())
+ if (State.isUnknown())
return; // Operands are not resolved yet.
if (SCCPSolver::isOverdefined(State))
return (void)markOverdefined(&CB);
@@ -1928,7 +1880,7 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
SmallVector<ConstantRange, 2> OpRanges;
for (Value *Op : II->args()) {
const ValueLatticeElement &State = getValueState(Op);
- if (State.isUnknownOrUndef())
+ if (State.isUnknown())
return;
OpRanges.push_back(
State.asConstantRange(Op->getType(), /*UndefAllowed=*/false));
@@ -2020,90 +1972,6 @@ void SCCPInstVisitor::solve() {
}
}
-bool SCCPInstVisitor::resolvedUndef(Instruction &I) {
- // Look for instructions which produce undef values.
- if (I.getType()->isVoidTy())
- return false;
-
- if (auto *STy = dyn_cast<StructType>(I.getType())) {
- // Only a few things that can be structs matter for undef.
-
- // Tracked calls must never be marked overdefined in resolvedUndefsIn.
- if (auto *CB = dyn_cast<CallBase>(&I))
- if (Function *F = CB->getCalledFunction())
- if (MRVFunctionsTracked.count(F))
- return false;
-
- // extractvalue and insertvalue don't need to be marked; they are
- // tracked as precisely as their operands.
- if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
- return false;
- // Send the results of everything else to overdefined. We could be
- // more precise than this but it isn't worth bothering.
- for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- ValueLatticeElement &LV = getStructValueState(&I, i);
- if (LV.isUnknown()) {
- markOverdefined(LV, &I);
- return true;
- }
- }
- return false;
- }
-
- ValueLatticeElement &LV = getValueState(&I);
- if (!LV.isUnknown())
- return false;
-
- // There are two reasons a call can have an undef result
- // 1. It could be tracked.
- // 2. It could be constant-foldable.
- // Because of the way we solve return values, tracked calls must
- // never be marked overdefined in resolvedUndefsIn.
- if (auto *CB = dyn_cast<CallBase>(&I))
- if (Function *F = CB->getCalledFunction())
- if (TrackedRetVals.count(F))
- return false;
-
- if (isa<LoadInst>(I)) {
- // A load here means one of two things: a load of undef from a global,
- // a load from an unknown pointer. Either way, having it return undef
- // is okay.
- return false;
- }
-
- markOverdefined(&I);
- return true;
-}
-
-/// While solving the dataflow for a function, we don't compute a result for
-/// operations with an undef operand, to allow undef to be lowered to a
-/// constant later. For example, constant folding of "zext i8 undef to i16"
-/// would result in "i16 0", and if undef is later lowered to "i8 1", then the
-/// zext result would become "i16 1" and would result into an overdefined
-/// lattice value once merged with the previous result. Not computing the
-/// result of the zext (treating undef the same as unknown) allows us to handle
-/// a later undef->constant lowering more optimally.
-///
-/// However, if the operand remains undef when the solver returns, we do need
-/// to assign some result to the instruction (otherwise we would treat it as
-/// unreachable). For simplicity, we mark any instructions that are still
-/// unknown as overdefined.
-bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
- bool MadeChange = false;
- for (BasicBlock &BB : F) {
- if (!BBExecutable.count(&BB))
- continue;
-
- for (Instruction &I : BB)
- MadeChange |= resolvedUndef(I);
- }
-
- LLVM_DEBUG(if (MadeChange) dbgs()
- << "\nResolved undefs in " << F.getName() << '\n');
-
- return MadeChange;
-}
-
//===----------------------------------------------------------------------===//
//
// SCCPSolver implementations
@@ -2155,23 +2023,6 @@ bool SCCPSolver::isArgumentTrackedFunction(Function *F) {
void SCCPSolver::solve() { Visitor->solve(); }
-bool SCCPSolver::resolvedUndefsIn(Function &F) {
- return Visitor->resolvedUndefsIn(F);
-}
-
-void SCCPSolver::solveWhileResolvedUndefsIn(Module &M) {
- Visitor->solveWhileResolvedUndefsIn(M);
-}
-
-void
-SCCPSolver::solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList) {
- Visitor->solveWhileResolvedUndefsIn(WorkList);
-}
-
-void SCCPSolver::solveWhileResolvedUndefs() {
- Visitor->solveWhileResolvedUndefs();
-}
-
bool SCCPSolver::isBlockExecutable(BasicBlock *BB) const {
return Visitor->isBlockExecutable(BB);
}
@@ -2193,6 +2044,10 @@ void SCCPSolver::resetLatticeValueFor(CallBase *Call) {
Visitor->resetLatticeValueFor(Call);
}
+void SCCPSolver::resetInvalidated() {
+ Visitor->resetInvalidated();
+}
+
const ValueLatticeElement &SCCPSolver::getLatticeValueFor(Value *V) const {
return Visitor->getLatticeValueFor(V);
}
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/abs.ll b/llvm/test/Transforms/CorrelatedValuePropagation/abs.ll
index 7f10ce63e2fdcd..09c03e3e8b5690 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/abs.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/abs.ll
@@ -499,7 +499,8 @@ define i32 @pr68381_undef_abs_true(i1 %c0, i1 %c1, i8 %v1) {
; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ]
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]]
; CHECK: bb2:
-; CHECK-NEXT: ret i32 [[X]]
+; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 true)
+; CHECK-NEXT: ret i32 [[Z]]
;
start:
br i1 %c0, label %bb0, label %bb1
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll
index 1d70932ee857b7..2c0a7890e50d72 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll
@@ -57,8 +57,10 @@ define i64 @constant_range_and_undef(i1 %cond, i64 %a) {
; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[T_1]])
; CHECK-NEXT: ret i64 [[RES]]
;
entry:
@@ -161,9 +163,12 @@ define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {
; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[P]], 256
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[T_1]])
+; CHECK-NEXT: ret i1 [[C]]
;
entry:
br i1 %cond, label %bb1, label %bb2
@@ -206,8 +211,10 @@ define i64 @constant_range_and_undef_3_incoming_v1(i1 %c1, i1 %c2, i64 %a) {
; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[T_1]])
; CHECK-NEXT: ret i64 [[RES]]
;
entry:
@@ -254,8 +261,10 @@ define i64 @constant_range_and_undef_3_incoming_v2(i1 %c1, i1 %c2, i64 %a) {
; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[T_1]])
; CHECK-NEXT: ret i64 [[RES]]
;
entry:
@@ -302,8 +311,10 @@ define i64 @constant_range_and_undef_3_incoming_v3(i1 %c1, i1 %c2, i64 %a) {
; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[T_1]])
; CHECK-NEXT: ret i64 [[RES]]
;
entry:
@@ -347,11 +358,14 @@ define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {
; CHECK-NEXT: br label [[BB5]]
; CHECK: bb5:
; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ]
+; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
-; CHECK-NEXT: ret i64 [[P]]
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
+; CHECK-NEXT: call void @use(i1 [[T_1]])
+; CHECK-NEXT: ret i64 [[RES]]
;
entry:
br i1 %c1, label %bb1, label %bb2
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/urem.ll b/llvm/test/Transforms/CorrelatedValuePropagation/urem.ll
index ec6461e29f1917..0b9325e4790e45 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/urem.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/urem.ll
@@ -441,7 +441,7 @@ define i8 @urem_undef_range_op2(i8 %x) {
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi i8 [ 5, [[CASE1]] ], [ 6, [[CASE2]] ], [ undef, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[RES:%.*]] = sub nuw i8 7, [[PHI]]
+; CHECK-NEXT: [[RES:%.*]] = urem i8 7, [[PHI]]
; CHECK-NEXT: ret i8 [[RES]]
;
entry:
diff --git a/llvm/test/Transforms/FunctionSpecialization/bug52821-use-after-free.ll b/llvm/test/Transforms/FunctionSpecialization/bug52821-use-after-free.ll
index 3892273aac8a05..01f05aa7fcaf0b 100644
--- a/llvm/test/Transforms/FunctionSpecialization/bug52821-use-after-free.ll
+++ b/llvm/test/Transforms/FunctionSpecialization/bug52821-use-after-free.ll
@@ -10,8 +10,10 @@ define internal ptr @myfunc(ptr %arg) {
; CHECK: for.cond:
; CHECK-NEXT: br label [[FOR_COND2:%.*]]
; CHECK: for.cond2:
-; CHECK-NEXT: br label [[FOR_BODY2:%.*]]
+; CHECK-NEXT: [[PHI2:%.*]] = phi ptr [ undef, [[FOR_BODY2:%.*]] ], [ null, [[FOR_COND]] ]
+; CHECK-NEXT: br label [[FOR_BODY2]]
; CHECK: for.body2:
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[MYSTRUCT:%.*]], ptr [[PHI2]], i64 0, i32 1, i64 3
; CHECK-NEXT: br label [[FOR_COND2]]
;
entry:
@@ -42,7 +44,7 @@ define ptr @caller() {
; CHECK-LABEL: @caller(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call ptr @myfunc(ptr undef)
-; CHECK-NEXT: ret ptr undef
+; CHECK-NEXT: ret ptr poison
;
entry:
%call = call ptr @myfunc(ptr undef)
diff --git a/llvm/test/Transforms/FunctionSpecialization/identical-specializations.ll b/llvm/test/Transforms/FunctionSpecialization/identical-specializations.ll
index 368f3b04403447..eca8dc211c64a5 100644
--- a/llvm/test/Transforms/FunctionSpecialization/identical-specializations.ll
+++ b/llvm/test/Transforms/FunctionSpecialization/identical-specializations.ll
@@ -12,9 +12,8 @@ define i64 @main(i64 %x, i64 %y, i1 %flag) {
; CHECK-NEXT: [[CMP1:%.*]] = call i64 @compute.specialized.3(i64 [[X]], i64 [[Y]], ptr @minus, ptr @plus)
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
-; CHECK-NEXT: [[PH:%.*]] = phi i64 [ [[CMP0]], [[PLUS]] ], [ [[CMP1]], [[MINUS]] ]
-; CHECK-NEXT: [[CMP2:%.*]] = call i64 @compute.specialized.2(i64 [[PH]], i64 42, ptr @plus, ptr @minus)
-; CHECK-NEXT: ret i64 [[CMP2]]
+; CHECK-NEXT: [[CMP2:%.*]] = call i64 @compute.specialized.2(i64 poison, i64 42, ptr @plus, ptr @minus)
+; CHECK-NEXT: ret i64 poison
;
entry:
br i1 %flag, label %plus, label %minus
@@ -48,6 +47,10 @@ entry:
define internal i64 @plus(i64 %x, i64 %y) {
; CHECK-LABEL: @plus(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: ret i64 [[ADD]]
+;
entry:
%add = add i64 %x, %y
ret i64 %add
@@ -55,25 +58,14 @@ entry:
define internal i64 @minus(i64 %x, i64 %y) {
; CHECK-LABEL: @minus(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: ret i64 [[SUB]]
+;
entry:
%sub = sub i64 %x, %y
ret i64 %sub
}
-; CHECK-LABEL: @compute.specialized.1
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP0:%.*]] = call i64 %binop1(i64 [[X:%.*]], i64 [[Y:%.*]])
-; CHECK-NEXT: [[CMP1:%.*]] = call i64 @plus(i64 [[X]], i64 [[Y]])
-; CHECK-NEXT: [[CMP2:%.*]] = call i64 @compute.specialized.1(i64 [[X]], i64 [[Y]], ptr %binop1, ptr @plus)
-; CHECK-LABEL: @compute.specialized.2
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP0:%.*]] = call i64 @plus(i64 [[X:%.*]], i64 [[Y:%.*]])
-; CHECK-NEXT: [[CMP1:%.*]] = call i64 @minus(i64 [[X]], i64 [[Y]])
-; CHECK-NEXT: [[CMP2:%.*]] = call i64 @compute.specialized.1(i64 [[X]], i64 [[Y]], ptr @plus, ptr @plus)
-; CHECK-LABEL: @compute.specialized.3
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP0:%.*]] = call i64 @minus(i64 [[X:%.*]], i64 [[Y:%.*]])
-; CHECK-NEXT: [[CMP1:%.*]] = call i64 @plus(i64 [[X]], i64 [[Y]])
-; CHECK-NEXT: [[CMP2:%.*]] = call i64 @compute.specialized.3(i64 [[X]], i64 [[Y]], ptr @minus, ptr @plus)
diff --git a/llvm/test/Transforms/JumpThreading/pr22086.ll b/llvm/test/Transforms/JumpThreading/pr22086.ll
index c7f9fcdbd34627..fdcd5d1e5297e2 100644
--- a/llvm/test/Transforms/JumpThreading/pr22086.ll
+++ b/llvm/test/Transforms/JumpThreading/pr22086.ll
@@ -5,9 +5,12 @@
define void @f() {
; CHECK-LABEL: define void @f() {
-; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[LOR_RHS:.*]]
; CHECK: [[LOR_RHS]]:
+; CHECK-NEXT: [[G_1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ 0, %[[LOR_RHS]] ]
+; CHECK-NEXT: [[SEXT:%.*]] = shl i32 [[G_1]], 16
+; CHECK-NEXT: [[CONV20:%.*]] = ashr exact i32 [[SEXT]], 16
; CHECK-NEXT: br label %[[LOR_RHS]]
;
entry:
diff --git a/llvm/test/Transforms/JumpThreading/thread-debug-info.ll b/llvm/test/Transforms/JumpThreading/thread-debug-info.ll
index cd7b0b1c05a801..189ef01661b184 100644
--- a/llvm/test/Transforms/JumpThreading/thread-debug-info.ll
+++ b/llvm/test/Transforms/JumpThreading/thread-debug-info.ll
@@ -96,10 +96,10 @@ exit: ; preds = %bb.f4, %bb.f3, %bb.
; being threaded, the `and` in the function below is optimised away, but its
; debug-info should still be preserved.
; Similarly, the call to f1 gets cloned, its dbg.value should be cloned too.
-define void @test16(i1 %c, i1 %c2, i1 %c3, i1 %c4) nounwind ssp !dbg !30 {
+define void @test16(i1 %c, i1 %c2, i1 %c3, i1 %c4, i32 %x) nounwind ssp !dbg !30 {
; CHECK-LABEL: define void @test16(i1
entry:
- %cmp = icmp sgt i32 undef, 1, !dbg !33
+ %cmp = icmp sgt i32 %x, 1, !dbg !33
br i1 %c, label %land.end, label %land.rhs, !dbg !33
land.rhs:
diff --git a/llvm/test/Transforms/LowerSwitch/condition-phi-unreachable-default.ll b/llvm/test/Transforms/LowerSwitch/condition-phi-unreachable-default.ll
index 09cb5b0918c913..525f577f09b00b 100644
--- a/llvm/test/Transforms/LowerSwitch/condition-phi-unreachable-default.ll
+++ b/llvm/test/Transforms/LowerSwitch/condition-phi-unreachable-default.ll
@@ -9,7 +9,7 @@ entry:
br label %sw.epilog
sw.epilog: ; preds = %sw.epilog.outer, %for.body
- %i = phi i32 [ undef, %for.body ], [ 0, %entry ]
+ %i = phi i32 [ poison, %for.body ], [ 0, %entry ]
br i1 undef, label %for.body, label %for.end
for.body: ; preds = %sw.epilog
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/constraint-elimination-placement.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/constraint-elimination-placement.ll
index 04bed80b55de2c..764275186ff5a7 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/constraint-elimination-placement.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/constraint-elimination-placement.ll
@@ -96,7 +96,7 @@ define void @test2(ptr %this) #0 {
; CHECK-LABEL: define void @test2(
; CHECK-SAME: ptr nocapture writeonly [[THIS:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL1_I_I:%.*]] = tail call i1 @test2_fn4(i8 undef)
+; CHECK-NEXT: [[CALL1_I_I:%.*]] = tail call i1 @test2_fn4(i8 poison)
; CHECK-NEXT: [[CALL2_I_I:%.*]] = load i64, ptr inttoptr (i64 8 to ptr), align 8
; CHECK-NEXT: [[COND_I_I:%.*]] = select i1 [[CALL1_I_I]], i64 [[CALL2_I_I]], i64 0
; CHECK-NEXT: switch i64 [[COND_I_I]], label [[COMMON_RET:%.*]] [
@@ -156,7 +156,7 @@ define i1 @test2_fn2(ptr %__rhs) #0 {
; CHECK-SAME: ptr nocapture readonly [[__RHS:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = tail call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[__RHS]])
-; CHECK-NEXT: [[CALL1_I:%.*]] = tail call i1 @test2_fn4(i8 undef)
+; CHECK-NEXT: [[CALL1_I:%.*]] = tail call i1 @test2_fn4(i8 poison)
; CHECK-NEXT: [[CALL2_I:%.*]] = load i64, ptr inttoptr (i64 8 to ptr), align 8
; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CALL1_I]], i64 [[CALL2_I]], i64 0
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i64 [[CALL]], [[COND_I]]
diff --git a/llvm/test/Transforms/SCCP/2006-12-19-UndefBug.ll b/llvm/test/Transforms/SCCP/2006-12-19-UndefBug.ll
index 0f3eea9aee144e..7d0e6bcac299f4 100644
--- a/llvm/test/Transforms/SCCP/2006-12-19-UndefBug.ll
+++ b/llvm/test/Transforms/SCCP/2006-12-19-UndefBug.ll
@@ -3,8 +3,7 @@
define i1 @foo() {
; CHECK-LABEL: @foo(
-; CHECK-NEXT: [[X:%.*]] = and i1 false, undef
-; CHECK-NEXT: ret i1 [[X]]
+; CHECK-NEXT: ret i1 false
;
%X = and i1 false, undef ; <i1> [#uses=1]
ret i1 %X
diff --git a/llvm/test/Transforms/SCCP/PR16052.ll b/llvm/test/Transforms/SCCP/PR16052.ll
index 04f9ceeb07fa30..fbe8793305ca9c 100644
--- a/llvm/test/Transforms/SCCP/PR16052.ll
+++ b/llvm/test/Transforms/SCCP/PR16052.ll
@@ -5,12 +5,10 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i64 @fn2() {
-; CHECK-LABEL: define {{[^@]+}}@fn2()
+; CHECK-LABEL: define {{[^@]+}}@fn2() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = sext i32 undef to i64
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
-; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]])
-; CHECK-NEXT: ret i64 [[CALL2]]
+; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 poison)
+; CHECK-NEXT: ret i64 poison
;
entry:
%conv = sext i32 undef to i64
@@ -21,11 +19,9 @@ entry:
define internal i64 @fn1(i64 %p1) {
; CHECK-LABEL: define {{[^@]+}}@fn1
-; CHECK-SAME: (i64 [[P1:%.*]])
+; CHECK-SAME: (i64 [[P1:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
-; CHECK-NEXT: ret i64 [[COND]]
+; CHECK-NEXT: ret i64 poison
;
entry:
%tobool = icmp ne i64 %p1, 0
diff --git a/llvm/test/Transforms/SCCP/PR26044.ll b/llvm/test/Transforms/SCCP/PR26044.ll
index 90ac3101d0c23f..29512849004a7f 100644
--- a/llvm/test/Transforms/SCCP/PR26044.ll
+++ b/llvm/test/Transforms/SCCP/PR26044.ll
@@ -11,8 +11,8 @@ define void @fn2(ptr %P) {
; CHECK: for.cond1:
; CHECK-NEXT: unreachable
; CHECK: if.end:
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 undef)
-; CHECK-NEXT: store i32 [[CALL]], ptr [[P]], align 4
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 poison)
+; CHECK-NEXT: store i32 poison, ptr [[P]], align 4
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
;
entry:
@@ -33,9 +33,7 @@ define internal i32 @fn1(i32 %p1) {
; CHECK-LABEL: define {{[^@]+}}@fn1
; CHECK-SAME: (i32 [[P1:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 undef, 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 undef, i32 undef
-; CHECK-NEXT: ret i32 [[COND]]
+; CHECK-NEXT: ret i32 poison
;
entry:
%tobool = icmp ne i32 %p1, 0
@@ -51,8 +49,8 @@ define void @fn_no_null_opt(ptr %P) #0 {
; CHECK: for.cond1:
; CHECK-NEXT: unreachable
; CHECK: if.end:
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 undef)
-; CHECK-NEXT: store i32 [[CALL]], ptr [[P]], align 4
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 poison)
+; CHECK-NEXT: store i32 poison, ptr [[P]], align 4
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
;
entry:
@@ -73,9 +71,7 @@ define internal i32 @fn0(i32 %p1) {
; CHECK-LABEL: define {{[^@]+}}@fn0
; CHECK-SAME: (i32 [[P1:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 undef, 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 undef, i32 undef
-; CHECK-NEXT: ret i32 [[COND]]
+; CHECK-NEXT: ret i32 poison
;
entry:
%tobool = icmp ne i32 %p1, 0
diff --git a/llvm/test/Transforms/SCCP/apint-bigint2.ll b/llvm/test/Transforms/SCCP/apint-bigint2.ll
index 695d6a4cf056f8..25fa1f16fab837 100644
--- a/llvm/test/Transforms/SCCP/apint-bigint2.ll
+++ b/llvm/test/Transforms/SCCP/apint-bigint2.ll
@@ -21,11 +21,7 @@ define i101 @array() {
define i101 @large_aggregate() {
; CHECK-LABEL: @large_aggregate(
-; CHECK-NEXT: [[D:%.*]] = and i101 undef, 1
-; CHECK-NEXT: [[DD:%.*]] = or i101 [[D]], 1
-; CHECK-NEXT: [[G:%.*]] = getelementptr i101, ptr getelementptr inbounds (i8, ptr @Y, i64 80), i101 [[DD]]
-; CHECK-NEXT: [[L3:%.*]] = load i101, ptr [[G]], align 4
-; CHECK-NEXT: ret i101 [[L3]]
+; CHECK-NEXT: ret i101 poison
;
%B = load i101, ptr undef
%D = and i101 %B, 1
@@ -38,11 +34,7 @@ define i101 @large_aggregate() {
define i101 @large_aggregate_2() {
; CHECK-LABEL: @large_aggregate_2(
-; CHECK-NEXT: [[D:%.*]] = and i101 undef, 1
-; CHECK-NEXT: [[DD:%.*]] = or i101 [[D]], 1
-; CHECK-NEXT: [[G:%.*]] = getelementptr i101, ptr getelementptr inbounds (i8, ptr @Y, i64 80), i101 [[DD]]
-; CHECK-NEXT: [[L3:%.*]] = load i101, ptr [[G]], align 4
-; CHECK-NEXT: ret i101 [[L3]]
+; CHECK-NEXT: ret i101 poison
;
%D = and i101 undef, 1
%DD = or i101 %D, 1
diff --git a/llvm/test/Transforms/SCCP/apint-select.ll b/llvm/test/Transforms/SCCP/apint-select.ll
index de424282d0168f..65b5e566170dfb 100644
--- a/llvm/test/Transforms/SCCP/apint-select.ll
+++ b/llvm/test/Transforms/SCCP/apint-select.ll
@@ -5,10 +5,7 @@
define i712 @test1() {
; CHECK-LABEL: @test1(
-; CHECK-NEXT: [[BB:%.*]] = and i64 ptrtoint (ptr @A to i64), undef
-; CHECK-NEXT: [[C:%.*]] = icmp sge i64 [[BB]], 0
-; CHECK-NEXT: [[X:%.*]] = select i1 [[C]], i712 0, i712 1
-; CHECK-NEXT: ret i712 [[X]]
+; CHECK-NEXT: ret i712 0
;
%B = ptrtoint ptr @A to i64
%BB = and i64 %B, undef
@@ -21,7 +18,8 @@ define i712 @test1() {
define i712 @test2(i1 %C) {
; CHECK-LABEL: @test2(
-; CHECK-NEXT: ret i712 0
+; CHECK-NEXT: [[X:%.*]] = select i1 [[C:%.*]], i712 0, i712 undef
+; CHECK-NEXT: ret i712 [[X]]
;
%X = select i1 %C, i712 0, i712 undef
ret i712 %X
diff --git a/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll b/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
index b0e97421cffb44..8f11ccb5c0ccdd 100644
--- a/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
+++ b/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll
@@ -102,9 +102,7 @@ define void @urem_cmp_constants() {
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: [[UREM_3:%.*]] = urem i16 12704, 0
-; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[UREM_3]], 1
-; CHECK-NEXT: call void @use(i1 [[C_5]])
+; CHECK-NEXT: call void @use(i1 poison)
; CHECK-NEXT: ret void
;
%sel = select i1 false, i16 0, i16 12704
@@ -130,9 +128,7 @@ define void @srem_cmp_constants() {
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: [[SREM_3:%.*]] = urem i16 12704, 0
-; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[SREM_3]], 1
-; CHECK-NEXT: call void @use(i1 [[C_5]])
+; CHECK-NEXT: call void @use(i1 poison)
; CHECK-NEXT: ret void
;
%sel = select i1 false, i16 0, i16 12704
diff --git a/llvm/test/Transforms/SCCP/conditions-ranges-with-undef.ll b/llvm/test/Transforms/SCCP/conditions-ranges-with-undef.ll
index 8b4dea462757e5..f544a4362fa662 100644
--- a/llvm/test/Transforms/SCCP/conditions-ranges-with-undef.ll
+++ b/llvm/test/Transforms/SCCP/conditions-ranges-with-undef.ll
@@ -8,8 +8,7 @@ declare void @use(i1)
define void @val_undef_eq() {
; CHECK-LABEL: @val_undef_eq(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 undef, 0
-; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 [[A]], 10
+; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 undef, 10
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-NEXT: call void @use(i1 false)
@@ -41,12 +40,11 @@ declare void @use.i32(i32)
define void @val_undef_range() {
; CHECK-LABEL: @val_undef_range(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 undef, 0
-; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[A]], 127
+; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 undef, 127
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127
+; CHECK-NEXT: [[A_127:%.*]] = and i32 undef, 127
; CHECK-NEXT: call void @use.i32(i32 [[A_127]])
; CHECK-NEXT: ret void
; CHECK: false:
@@ -79,12 +77,16 @@ define void @val_singlecrfromundef_range(i1 %cond) {
; CHECK: inc2:
; CHECK-NEXT: br label [[IF]]
; CHECK: if:
-; CHECK-NEXT: br label [[TRUE:%.*]]
+; CHECK-NEXT: [[P:%.*]] = phi i32 [ 10, [[INC1]] ], [ undef, [[INC2]] ]
+; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[P]], 127
+; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: [[P_127:%.*]] = and i32 10, 127
+; CHECK-NEXT: [[P_127:%.*]] = and i32 [[P]], 127
; CHECK-NEXT: call void @use.i32(i32 [[P_127]])
; CHECK-NEXT: ret void
+; CHECK: false:
+; CHECK-NEXT: ret void
;
entry:
@@ -175,11 +177,14 @@ define void @bound_singlecrfromundef(i32 %a, i1 %cond) {
; CHECK: bb2:
; CHECK-NEXT: br label [[PRED]]
; CHECK: pred:
-; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], 10
+; CHECK-NEXT: [[P:%.*]] = phi i32 [ undef, [[BB1]] ], [ 10, [[BB2]] ]
+; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], [[P]]
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
-; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[A]], 5
+; CHECK-NEXT: call void @use(i1 [[F_1]])
+; CHECK-NEXT: [[T_1:%.*]] = icmp ne i32 [[A]], 5
+; CHECK-NEXT: call void @use(i1 [[T_1]])
; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127
; CHECK-NEXT: call void @use.i32(i32 [[A_127]])
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/SCCP/divrem-crash.ll b/llvm/test/Transforms/SCCP/divrem-crash.ll
index e559e6e68bf41a..458739400052de 100644
--- a/llvm/test/Transforms/SCCP/divrem-crash.ll
+++ b/llvm/test/Transforms/SCCP/divrem-crash.ll
@@ -5,8 +5,7 @@
define i32 @sdiv_const_undef() {
; CHECK-LABEL: @sdiv_const_undef(
-; CHECK-NEXT: [[D:%.*]] = sdiv i32 42, poison
-; CHECK-NEXT: ret i32 [[D]]
+; CHECK-NEXT: ret i32 poison
;
%i = load i32, ptr @g, align 4
%d = sdiv i32 %i, poison
@@ -15,8 +14,7 @@ define i32 @sdiv_const_undef() {
define i32 @sdiv_undef_const() {
; CHECK-LABEL: @sdiv_undef_const(
-; CHECK-NEXT: [[D:%.*]] = sdiv i32 poison, 42
-; CHECK-NEXT: ret i32 [[D]]
+; CHECK-NEXT: ret i32 poison
;
%i = load i32, ptr @g, align 4
%d = sdiv i32 poison, %i
diff --git a/llvm/test/Transforms/SCCP/float-phis.ll b/llvm/test/Transforms/SCCP/float-phis.ll
index 208fc1dc4e1a61..3c519863dc0a2d 100644
--- a/llvm/test/Transforms/SCCP/float-phis.ll
+++ b/llvm/test/Transforms/SCCP/float-phis.ll
@@ -9,7 +9,9 @@ define void @test(i1 %c) {
; CHECK: do.body:
; CHECK-NEXT: br i1 [[C:%.*]], label [[DO_BODY]], label [[FOR_COND41:%.*]]
; CHECK: for.cond41:
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[MID_0:%.*]] = phi float [ 0.000000e+00, [[FOR_COND41]] ], [ undef, [[DO_BODY]] ]
+; CHECK-NEXT: [[FC:%.*]] = fcmp oeq float [[MID_0]], 0.000000e+00
+; CHECK-NEXT: call void @use(i1 [[FC]])
; CHECK-NEXT: br label [[FOR_COND41]]
;
br label %do.body
diff --git a/llvm/test/Transforms/SCCP/int-phis.ll b/llvm/test/Transforms/SCCP/int-phis.ll
index d2641952d7f326..d56c2c4635242c 100644
--- a/llvm/test/Transforms/SCCP/int-phis.ll
+++ b/llvm/test/Transforms/SCCP/int-phis.ll
@@ -9,12 +9,14 @@ define void @read_dmatrix() #0 {
; CHECK-NEXT: [[HEIGHT:%.*]] = alloca i32, align 4
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
+; CHECK-NEXT: [[J_0:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ 0, [[FOR_COND6:%.*]] ]
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[HEIGHT]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP0]]
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND6:%.*]], label [[FOR_END16:%.*]]
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND6]], label [[FOR_END16:%.*]]
; CHECK: for.cond6:
; CHECK-NEXT: br label [[FOR_COND]]
; CHECK: for.end16:
+; CHECK-NEXT: [[SUB21:%.*]] = sub nsw i32 [[J_0]], 1
; CHECK-NEXT: ret void
;
entry:
@@ -42,6 +44,8 @@ define void @emptyTT() #0 {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
+; CHECK-NEXT: [[DOTCOMPOUNDLITERAL_SROA_0_0:%.*]] = phi i64 [ undef, [[ENTRY:%.*]] ], [ 0, [[FOR_COND]] ]
+; CHECK-NEXT: [[BF_CLEAR:%.*]] = and i64 [[DOTCOMPOUNDLITERAL_SROA_0_0]], -67108864
; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C]], label [[FOR_COND]], label [[EXIT:%.*]]
; CHECK: exit:
diff --git a/llvm/test/Transforms/SCCP/intrinsics.ll b/llvm/test/Transforms/SCCP/intrinsics.ll
index 5edb31738e685b..f6d38b8966db70 100644
--- a/llvm/test/Transforms/SCCP/intrinsics.ll
+++ b/llvm/test/Transforms/SCCP/intrinsics.ll
@@ -107,7 +107,9 @@ define i8 @umax_including_undef(i1 %c.1, i1 %c.2) {
; CHECK: false:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
-; CHECK-NEXT: ret i8 3
+; CHECK-NEXT: [[P:%.*]] = phi i8 [ 3, [[TRUE]] ], [ undef, [[FALSE]] ]
+; CHECK-NEXT: [[P_UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[P]], i8 1)
+; CHECK-NEXT: ret i8 [[P_UMAX]]
;
br i1 %c.1, label %true, label %false
diff --git a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll
index c0cdfafe71cb2d..a540e830555ccb 100644
--- a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll
+++ b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll
@@ -205,7 +205,7 @@ define internal i32 @f5(i32 %x) {
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 undef, [[X]]
; CHECK-NEXT: [[RES1:%.*]] = select i1 [[CMP]], i32 1, i32 2
; CHECK-NEXT: [[RES2:%.*]] = select i1 [[CMP2]], i32 3, i32 4
-; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES1]], [[RES2]]
+; CHECK-NEXT: [[RES:%.*]] = add nuw nsw i32 [[RES1]], [[RES2]]
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
@@ -223,7 +223,7 @@ define i32 @caller4() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @f5(i32 47)
; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @f5(i32 301)
-; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
+; CHECK-NEXT: [[RES:%.*]] = add nuw nsw i32 [[CALL1]], [[CALL2]]
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
diff --git a/llvm/test/Transforms/SCCP/ipsccp-basic.ll b/llvm/test/Transforms/SCCP/ipsccp-basic.ll
index 9ab686aa701f44..d493e8089cfe5e 100644
--- a/llvm/test/Transforms/SCCP/ipsccp-basic.ll
+++ b/llvm/test/Transforms/SCCP/ipsccp-basic.ll
@@ -275,7 +275,7 @@ define i32 @test10a() nounwind {
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32 @test10b(i32 undef)
-; CHECK-NEXT: ret i32 [[CALL]]
+; CHECK-NEXT: ret i32 0
;
entry:
%call = call i32 @test10b(i32 undef)
@@ -287,8 +287,7 @@ define internal i32 @test10b(i32 %x) nounwind {
; CHECK-LABEL: define internal i32 @test10b
; CHECK-SAME: (i32 [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[R:%.*]] = and i32 undef, 1
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 poison
;
entry:
%r = and i32 %x, 1
@@ -299,8 +298,7 @@ entry:
define i64 @test11a() {
; CHECK-LABEL: define i64 @test11a() {
-; CHECK-NEXT: [[XOR:%.*]] = xor i64 undef, undef
-; CHECK-NEXT: ret i64 [[XOR]]
+; CHECK-NEXT: ret i64 0
;
%xor = xor i64 undef, undef
ret i64 %xor
@@ -309,8 +307,7 @@ define i64 @test11a() {
define i64 @test11b() {
; CHECK-LABEL: define i64 @test11b() {
; CHECK-NEXT: [[CALL1:%.*]] = call i64 @test11a()
-; CHECK-NEXT: [[CALL2:%.*]] = call i64 @llvm.ctpop.i64(i64 [[CALL1]])
-; CHECK-NEXT: ret i64 [[CALL2]]
+; CHECK-NEXT: ret i64 0
;
%call1 = call i64 @test11a()
%call2 = call i64 @llvm.ctpop.i64(i64 %call1)
diff --git a/llvm/test/Transforms/SCCP/loadtest2.ll b/llvm/test/Transforms/SCCP/loadtest2.ll
index 28cea91d056e43..53fb3956f28ff4 100644
--- a/llvm/test/Transforms/SCCP/loadtest2.ll
+++ b/llvm/test/Transforms/SCCP/loadtest2.ll
@@ -7,8 +7,7 @@
define i32 @test5(i32 %b) {
; CHECK-LABEL: define i32 @test5(
; CHECK-SAME: i32 [[B:%.*]]) {
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 undef, [[B]]
-; CHECK-NEXT: ret i32 [[ADD]]
+; CHECK-NEXT: ret i32 undef
;
%l = load i32, ptr @j, align 4
%add = add nsw i32 %l, %b
diff --git a/llvm/test/Transforms/SCCP/logical-nuke.ll b/llvm/test/Transforms/SCCP/logical-nuke.ll
index c42ecc660995fd..ab00aad7819b2d 100644
--- a/llvm/test/Transforms/SCCP/logical-nuke.ll
+++ b/llvm/test/Transforms/SCCP/logical-nuke.ll
@@ -3,7 +3,7 @@
; Test that SCCP has basic knowledge of when and/or/mul nuke overdefined values.
- define i32 @test(i32 %X) {
+ define i32 @test(i32 %X) {
; CHECK-LABEL: @test(
; CHECK-NEXT: ret i32 0
;
@@ -21,8 +21,7 @@ define i32 @test2(i32 %X) {
define i32 @test3(i32 %X) {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[Y:%.*]] = and i32 undef, [[X:%.*]]
-; CHECK-NEXT: ret i32 [[Y]]
+; CHECK-NEXT: ret i32 0
;
%Y = and i32 undef, %X
ret i32 %Y
@@ -30,8 +29,7 @@ define i32 @test3(i32 %X) {
define i32 @test4(i32 %X) {
; CHECK-LABEL: @test4(
-; CHECK-NEXT: [[Y:%.*]] = or i32 [[X:%.*]], undef
-; CHECK-NEXT: ret i32 [[Y]]
+; CHECK-NEXT: ret i32 -1
;
%Y = or i32 %X, undef
ret i32 %Y
diff --git a/llvm/test/Transforms/SCCP/overdefined-div.ll b/llvm/test/Transforms/SCCP/overdefined-div.ll
index 5f23d12037407e..39b4715d93b210 100644
--- a/llvm/test/Transforms/SCCP/overdefined-div.ll
+++ b/llvm/test/Transforms/SCCP/overdefined-div.ll
@@ -25,8 +25,7 @@ define i32 @test2(i32 %foo) {
define i32 @test3(i32 %foo) {
; CHECK-LABEL: define i32 @test3
; CHECK-SAME: (i32 [[FOO:%.*]]) {
-; CHECK-NEXT: [[TINKYWINKY:%.*]] = udiv i32 [[FOO]], 0
-; CHECK-NEXT: ret i32 [[TINKYWINKY]]
+; CHECK-NEXT: ret i32 poison
;
%tinkywinky = udiv i32 %foo, 0
ret i32 %tinkywinky
@@ -35,8 +34,7 @@ define i32 @test3(i32 %foo) {
define i32 @test4(i32 %foo) {
; CHECK-LABEL: define i32 @test4
; CHECK-SAME: (i32 [[FOO:%.*]]) {
-; CHECK-NEXT: [[TINKYWINKY:%.*]] = sdiv i32 [[FOO]], 0
-; CHECK-NEXT: ret i32 [[TINKYWINKY]]
+; CHECK-NEXT: ret i32 poison
;
%tinkywinky = sdiv i32 %foo, 0
ret i32 %tinkywinky
diff --git a/llvm/test/Transforms/SCCP/phi-cycle.ll b/llvm/test/Transforms/SCCP/phi-cycle.ll
index 814fe174d4b391..c330f0eb3119e3 100644
--- a/llvm/test/Transforms/SCCP/phi-cycle.ll
+++ b/llvm/test/Transforms/SCCP/phi-cycle.ll
@@ -8,13 +8,14 @@ define i32 @test() {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
+; CHECK-NEXT: [[P:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ 0, [[LATCH_2:%.*]] ], [ [[P]], [[LOOP]] ]
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
-; CHECK-NEXT: br i1 [[C_1]], label [[LOOP]], label [[LATCH_2:%.*]]
+; CHECK-NEXT: br i1 [[C_1]], label [[LOOP]], label [[LATCH_2]]
; CHECK: latch.2:
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 [[P]]
;
entry:
br label %loop
diff --git a/llvm/test/Transforms/SCCP/range-and-ip.ll b/llvm/test/Transforms/SCCP/range-and-ip.ll
index d5d4b8022e1a7e..adee121bf26695 100644
--- a/llvm/test/Transforms/SCCP/range-and-ip.ll
+++ b/llvm/test/Transforms/SCCP/range-and-ip.ll
@@ -15,7 +15,9 @@ define i1 @constant_and_undef(i64 %a) {
; CHECK: [[BB2]]:
; CHECK-NEXT: [[RANGE:%.*]] = and i64 [[A]], 255
; CHECK-NEXT: [[C_3:%.*]] = call i1 @f1(i64 [[RANGE]])
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[R_1:%.*]] = and i1 [[C_1]], [[C_2]]
+; CHECK-NEXT: [[R_2:%.*]] = and i1 [[R_1]], [[C_3]]
+; CHECK-NEXT: ret i1 [[R_2]]
;
%c.1 = call i1 @f1(i64 undef)
br label %bb1
@@ -37,8 +39,9 @@ declare void @sideeffect(i1, i64 %a)
define internal i1 @f1(i64 %r) {
; CHECK-LABEL: define internal i1 @f1(
; CHECK-SAME: i64 [[R:%.*]]) {
-; CHECK-NEXT: call void @sideeffect(i1 true, i64 [[R]])
-; CHECK-NEXT: ret i1 poison
+; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[R]], 256
+; CHECK-NEXT: call void @sideeffect(i1 [[C]], i64 [[R]])
+; CHECK-NEXT: ret i1 [[C]]
;
%c = icmp ult i64 %r, 256
call void @sideeffect(i1 %c, i64 %r)
diff --git a/llvm/test/Transforms/SCCP/range-and.ll b/llvm/test/Transforms/SCCP/range-and.ll
index ef8758fcba9e22..8f2b932864e3ce 100644
--- a/llvm/test/Transforms/SCCP/range-and.ll
+++ b/llvm/test/Transforms/SCCP/range-and.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --verbose
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=sccp %s | FileCheck %s
declare void @use(i1)
@@ -46,7 +46,9 @@ define i64 @constant_and_undef(i1 %c1, i64 %a) {
; CHECK: bb2:
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
-; CHECK-NEXT: ret i64 0
+; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ 0, [[BB2]] ]
+; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
+; CHECK-NEXT: ret i64 [[RES]]
;
entry:
br i1 %c1, label %bb1, label %bb2
@@ -169,13 +171,12 @@ define i64 @constant_range_and_undef2(i1 %c1, i1 %c2, i64 %a) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[V1:%.*]] = add i64 undef, undef
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[V2:%.*]] = and i64 [[A:%.*]], 255
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
-; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[V1]], [[BB1]] ], [ [[V2]], [[BB2]] ]
+; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[V2]], [[BB2]] ]
; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
; CHECK: bb4:
; CHECK-NEXT: br label [[BB6:%.*]]
@@ -226,7 +227,8 @@ define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[P]], 256
+; CHECK-NEXT: ret i1 [[C]]
;
entry:
br i1 %cond, label %bb1, label %bb2
@@ -255,7 +257,8 @@ define i1 @constant_range_and_undef_3_switched_incoming(i1 %cond, i64 %a) {
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ]
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[P]], 256
+; CHECK-NEXT: ret i1 [[C]]
;
entry:
br i1 %cond, label %bb1, label %bb2
@@ -397,9 +400,10 @@ define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {
; CHECK: bb3:
; CHECK-NEXT: br label [[BB4]]
; CHECK: bb4:
+; CHECK-NEXT: [[P_1:%.*]] = phi i64 [ 10, [[BB2]] ], [ undef, [[BB3]] ]
; CHECK-NEXT: br label [[BB5]]
; CHECK: bb5:
-; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ]
+; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ [[P_1]], [[BB4]] ]
; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: ret i64 [[RES]]
;
diff --git a/llvm/test/Transforms/SCCP/recursion.ll b/llvm/test/Transforms/SCCP/recursion.ll
index f6556bee3eaba1..171c7b85b23607 100644
--- a/llvm/test/Transforms/SCCP/recursion.ll
+++ b/llvm/test/Transforms/SCCP/recursion.ll
@@ -5,9 +5,8 @@
define internal i32 @foo(i32 %X) {
; CHECK-LABEL: @foo(
-; CHECK-NEXT: [[Y:%.*]] = call i32 @foo()
-; CHECK-NEXT: [[Z:%.*]] = add i32 [[Y]], 1
-; CHECK-NEXT: ret i32 [[Z]]
+; CHECK-NEXT: call void @foo()
+; CHECK-NEXT: ret void
;
%Y = call i32 @foo( i32 %X ) ; <i32> [#uses=1]
%Z = add i32 %Y, 1 ; <i32> [#uses=1]
@@ -16,7 +15,7 @@ define internal i32 @foo(i32 %X) {
define void @bar() {
; CHECK-LABEL: @bar(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @foo()
+; CHECK-NEXT: call void @foo()
; CHECK-NEXT: ret void
;
call i32 @foo( i32 17 ) ; <i32>:1 [#uses=0]
diff --git a/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll b/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll
index 88e9e6568c6475..1c461ff03e8eef 100644
--- a/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll
+++ b/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll
@@ -260,7 +260,7 @@ define void @test4_a() {
; CHECK-LABEL: define {{[^@]+}}@test4_a() {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = call ptr @test4_c(ptr null)
-; CHECK-NEXT: call void @test4_b(ptr null)
+; CHECK-NEXT: call void @test4_b(ptr poison)
; CHECK-NEXT: ret void
;
bb:
@@ -273,9 +273,8 @@ define internal void @test4_b(ptr %arg) {
; CHECK-LABEL: define {{[^@]+}}@test4_b
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[SEL:%.*]] = select i1 false, ptr null, ptr null
-; CHECK-NEXT: call void @use.16(ptr null)
-; CHECK-NEXT: call void @use.8(ptr [[SEL]])
+; CHECK-NEXT: call void @use.16(ptr poison)
+; CHECK-NEXT: call void @use.8(ptr poison)
; CHECK-NEXT: ret void
;
bb:
@@ -289,12 +288,7 @@ define internal ptr @test4_c(ptr %arg) {
; CHECK-LABEL: define {{[^@]+}}@test4_c
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: bb1:
-; CHECK-NEXT: [[TMP:%.*]] = and i1 undef, undef
-; CHECK-NEXT: br i1 [[TMP]], label [[BB3:%.*]], label [[BB2:%.*]]
-; CHECK: bb2:
; CHECK-NEXT: unreachable
-; CHECK: bb3:
-; CHECK-NEXT: ret ptr poison
;
bb1: ; preds = %bb
%tmp = and i1 undef, undef
@@ -313,7 +307,7 @@ define void @test5_a() {
; CHECK-LABEL: define {{[^@]+}}@test5_a() {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = call ptr @test5_c(ptr null)
-; CHECK-NEXT: call void @test5_b(ptr null)
+; CHECK-NEXT: call void @test5_b(ptr poison)
; CHECK-NEXT: ret void
;
bb:
@@ -326,8 +320,7 @@ define internal void @test5_b(ptr %arg) {
; CHECK-LABEL: define {{[^@]+}}@test5_b
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[SEL:%.*]] = select i1 false, ptr null, ptr null
-; CHECK-NEXT: call void @use.8(ptr [[SEL]])
+; CHECK-NEXT: call void @use.8(ptr poison)
; CHECK-NEXT: ret void
;
bb:
@@ -340,12 +333,7 @@ define internal ptr @test5_c(ptr %arg) {
; CHECK-LABEL: define {{[^@]+}}@test5_c
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: bb1:
-; CHECK-NEXT: [[TMP:%.*]] = and i1 undef, undef
-; CHECK-NEXT: br i1 [[TMP]], label [[BB3:%.*]], label [[BB2:%.*]]
-; CHECK: bb2:
; CHECK-NEXT: unreachable
-; CHECK: bb3:
-; CHECK-NEXT: ret ptr poison
;
bb1: ; preds = %bb
%tmp = and i1 undef, undef
@@ -370,23 +358,11 @@ define void @test3() {
; CHECK-NEXT: br label [[IF_END16:%.*]]
; CHECK: if.end16:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @contextsize, align 4
-; CHECK-NEXT: [[SUB18:%.*]] = sub i32 undef, [[TMP0]]
-; CHECK-NEXT: [[SUB19:%.*]] = sub i32 [[SUB18]], undef
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @maxposslen, align 4
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], 8
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 undef, [[ADD]]
-; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @pcount, align 4
-; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], [[SUB19]]
-; CHECK-NEXT: [[CMP20:%.*]] = icmp sgt i32 [[TMP2]], [[MUL]]
-; CHECK-NEXT: br i1 [[CMP20]], label [[IF_THEN22:%.*]], label [[IF_END24:%.*]]
-; CHECK: if.then22:
-; CHECK-NEXT: store i32 [[MUL]], ptr @pcount, align 4
-; CHECK-NEXT: ret void
+; CHECK-NEXT: br label [[IF_END24:%.*]]
; CHECK: if.end24:
-; CHECK-NEXT: [[CMP25474:%.*]] = icmp sgt i32 [[TMP2]], 0
-; CHECK-NEXT: br i1 [[CMP25474]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-; CHECK: for.body:
-; CHECK-NEXT: ret void
+; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.end:
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/SCCP/return-zapped.ll b/llvm/test/Transforms/SCCP/return-zapped.ll
index 6d705001250930..3797c1fd751c51 100644
--- a/llvm/test/Transforms/SCCP/return-zapped.ll
+++ b/llvm/test/Transforms/SCCP/return-zapped.ll
@@ -47,7 +47,7 @@ define i1 @test2() {
; CHECK-NEXT: br label [[IF_END:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[CALL2:%.*]] = call i1 @testf()
-; CHECK-NEXT: ret i1 undef
+; CHECK-NEXT: ret i1 poison
;
entry:
br label %if.end
diff --git a/llvm/test/Transforms/SCCP/select.ll b/llvm/test/Transforms/SCCP/select.ll
index dfe44bb108f54c..f00d3c1999d058 100644
--- a/llvm/test/Transforms/SCCP/select.ll
+++ b/llvm/test/Transforms/SCCP/select.ll
@@ -13,7 +13,8 @@ define i32 @test1(i1 %C) {
define i32 @test2(i1 %C) {
; CHECK-LABEL: define i32 @test2(
; CHECK-SAME: i1 [[C:%.*]]) {
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: [[X:%.*]] = select i1 [[C]], i32 0, i32 undef
+; CHECK-NEXT: ret i32 [[X]]
;
%X = select i1 %C, i32 0, i32 undef
ret i32 %X
diff --git a/llvm/test/Transforms/SCCP/ub-shift.ll b/llvm/test/Transforms/SCCP/ub-shift.ll
index ae2739d0445d0e..6820c8c2d3d753 100644
--- a/llvm/test/Transforms/SCCP/ub-shift.ll
+++ b/llvm/test/Transforms/SCCP/ub-shift.ll
@@ -5,8 +5,7 @@ define void @shift_undef_64(ptr %p) {
; CHECK-LABEL: @shift_undef_64(
; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i64 -1, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i64 -1, 4294967298
-; CHECK-NEXT: store i64 [[R3]], ptr [[P]], align 4
+; CHECK-NEXT: store i64 poison, ptr [[P]], align 4
; CHECK-NEXT: ret void
;
%r1 = lshr i64 -1, 4294967296 ; 2^32
@@ -25,8 +24,7 @@ define void @shift_undef_65(ptr %p) {
; CHECK-LABEL: @shift_undef_65(
; CHECK-NEXT: store i65 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i65 0, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i65 1, -18446744073709551615
-; CHECK-NEXT: store i65 [[R3]], ptr [[P]], align 4
+; CHECK-NEXT: store i65 poison, ptr [[P]], align 4
; CHECK-NEXT: ret void
;
%r1 = lshr i65 2, 18446744073709551617
@@ -45,8 +43,7 @@ define void @shift_undef_256(ptr %p) {
; CHECK-LABEL: @shift_undef_256(
; CHECK-NEXT: store i256 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i256 0, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i256 1, 18446744073709551619
-; CHECK-NEXT: store i256 [[R3]], ptr [[P]], align 4
+; CHECK-NEXT: store i256 poison, ptr [[P]], align 4
; CHECK-NEXT: ret void
;
%r1 = lshr i256 2, 18446744073709551617
@@ -65,8 +62,7 @@ define void @shift_undef_511(ptr %p) {
; CHECK-LABEL: @shift_undef_511(
; CHECK-NEXT: store i511 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i511 -1, ptr [[P]], align 4
-; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i511 -3, 1208925819614629174706180
-; CHECK-NEXT: store i511 [[R3]], ptr [[P]], align 4
+; CHECK-NEXT: store i511 poison, ptr [[P]], align 4
; CHECK-NEXT: ret void
;
%r1 = lshr i511 -1, 1208925819614629174706276 ; 2^80 + 100
diff --git a/llvm/test/Transforms/SCCP/undef-resolve.ll b/llvm/test/Transforms/SCCP/undef-resolve.ll
index 8bb2baa82dce36..665ae723296c79 100644
--- a/llvm/test/Transforms/SCCP/undef-resolve.ll
+++ b/llvm/test/Transforms/SCCP/undef-resolve.ll
@@ -5,8 +5,7 @@
; PR6940
define double @test1() {
; CHECK-LABEL: @test1(
-; CHECK-NEXT: [[T:%.*]] = sitofp i32 undef to double
-; CHECK-NEXT: ret double [[T]]
+; CHECK-NEXT: ret double 0.000000e+00
;
%t = sitofp i32 undef to double
ret double %t
@@ -175,8 +174,7 @@ bb1: ; preds = %bb1.us-lcssa, %bb1.
; rdar://9956541
define i32 @test3() {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[T:%.*]] = xor i32 undef, undef
-; CHECK-NEXT: ret i32 [[T]]
+; CHECK-NEXT: ret i32 0
;
%t = xor i32 undef, undef
ret i32 %t
@@ -185,8 +183,7 @@ define i32 @test3() {
; Be conservative with FP ops
define double @test4(double %x) {
; CHECK-LABEL: @test4(
-; CHECK-NEXT: [[T:%.*]] = fadd double [[X:%.*]], undef
-; CHECK-NEXT: ret double [[T]]
+; CHECK-NEXT: ret double 0x7FF8000000000000
;
%t = fadd double %x, undef
ret double %t
@@ -195,8 +192,7 @@ define double @test4(double %x) {
; Make sure casts produce a possible value
define i32 @test5() {
; CHECK-LABEL: @test5(
-; CHECK-NEXT: [[T:%.*]] = sext i8 undef to i32
-; CHECK-NEXT: ret i32 [[T]]
+; CHECK-NEXT: ret i32 0
;
%t = sext i8 undef to i32
ret i32 %t
@@ -205,8 +201,7 @@ define i32 @test5() {
; Make sure ashr produces a possible value
define i32 @test6() {
; CHECK-LABEL: @test6(
-; CHECK-NEXT: [[T:%.*]] = ashr i32 undef, 31
-; CHECK-NEXT: ret i32 [[T]]
+; CHECK-NEXT: ret i32 0
;
%t = ashr i32 undef, 31
ret i32 %t
@@ -215,8 +210,7 @@ define i32 @test6() {
; Make sure lshr produces a possible value
define i32 @test7() {
; CHECK-LABEL: @test7(
-; CHECK-NEXT: [[T:%.*]] = lshr i32 undef, 31
-; CHECK-NEXT: ret i32 [[T]]
+; CHECK-NEXT: ret i32 0
;
%t = lshr i32 undef, 31
ret i32 %t
@@ -260,8 +254,7 @@ define i32 @test11(i1 %tobool) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr @test11, @GV
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i32
-; CHECK-NEXT: [[SHR4:%.*]] = ashr i32 undef, [[EXT]]
-; CHECK-NEXT: ret i32 [[SHR4]]
+; CHECK-NEXT: ret i32 0
;
entry:
%cmp = icmp eq ptr @test11, @GV
@@ -273,8 +266,7 @@ entry:
; Test unary ops
define double @test12(double %x) {
; CHECK-LABEL: @test12(
-; CHECK-NEXT: [[T:%.*]] = fneg double undef
-; CHECK-NEXT: ret double [[T]]
+; CHECK-NEXT: ret double undef
;
%t = fneg double undef
ret double %t
diff --git a/llvm/unittests/Analysis/ValueLatticeTest.cpp b/llvm/unittests/Analysis/ValueLatticeTest.cpp
index 1567bce2092986..ef15201de2ab17 100644
--- a/llvm/unittests/Analysis/ValueLatticeTest.cpp
+++ b/llvm/unittests/Analysis/ValueLatticeTest.cpp
@@ -172,6 +172,7 @@ TEST_F(ValueLatticeTest, getCompareFloat) {
TEST_F(ValueLatticeTest, getCompareUndef) {
auto *I32Ty = IntegerType::get(Context, 32);
auto *I1Ty = IntegerType::get(Context, 1);
+ Constant *False = ConstantInt::getFalse(Context);
// TODO: These results can be improved.
auto LV1 = ValueLatticeElement::get(UndefValue::get(I32Ty));
@@ -186,12 +187,12 @@ TEST_F(ValueLatticeTest, getCompareUndef) {
auto *FloatTy = IntegerType::getFloatTy(Context);
auto LV3 = ValueLatticeElement::get(ConstantFP::get(FloatTy, 1.0));
- EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV3, DL), nullptr);
- EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV3, DL), nullptr);
- EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV3, DL), nullptr);
- EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV3, DL), nullptr);
- EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV3, DL), nullptr);
- EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV3, DL), nullptr);
+ EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV3, DL), False);
+ EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV3, DL), False);
+ EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV3, DL), False);
+ EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV3, DL), False);
+ EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV3, DL), False);
+ EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV3, DL), False);
}
} // end anonymous namespace
diff --git a/llvm/unittests/Transforms/IPO/FunctionSpecializationTest.cpp b/llvm/unittests/Transforms/IPO/FunctionSpecializationTest.cpp
index 52bad210b583ed..61f16ee08745f1 100644
--- a/llvm/unittests/Transforms/IPO/FunctionSpecializationTest.cpp
+++ b/llvm/unittests/Transforms/IPO/FunctionSpecializationTest.cpp
@@ -89,7 +89,7 @@ class FunctionSpecializationTest : public testing::Test {
Solver->markBlockExecutable(&F->front());
for (Argument &Arg : F->args())
Solver->markOverdefined(&Arg);
- Solver->solveWhileResolvedUndefsIn(*M);
+ Solver->solve();
removeSSACopy(*F);
More information about the llvm-commits
mailing list