diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2675,14 +2675,7 @@ intersectAccessGroups(K, J)); break; case LLVMContext::MD_range: - - // If K does move, use most generic range. Otherwise keep the range of - // K. - if (DoesKMove) - // FIXME: If K does move, we should drop the range info and nonnull. - // Currently this function is used with DoesKMove in passes - // doing hoisting/sinking and the current behavior of using the - // most generic range is correct in those cases. + if (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)) K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD)); break; case LLVMContext::MD_fpmath: diff --git a/llvm/test/Transforms/GVN/range.ll b/llvm/test/Transforms/GVN/range.ll --- a/llvm/test/Transforms/GVN/range.ll +++ b/llvm/test/Transforms/GVN/range.ll @@ -17,7 +17,7 @@ define i32 @test2(ptr %p) { ; CHECK-LABEL: define i32 @test2 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -30,7 +30,7 @@ define i32 @test3(ptr %p) { ; CHECK-LABEL: define i32 @test3 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -43,7 +43,7 @@ define i32 @test4(ptr %p) { ; CHECK-LABEL: define i32 @test4 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG2:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -56,7 +56,7 @@ define i32 @test5(ptr %p) { ; CHECK-LABEL: define i32 @test5 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG3:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -69,7 +69,7 @@ define i32 @test6(ptr %p) { ; CHECK-LABEL: define i32 @test6 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG2:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG4:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -82,7 +82,7 @@ define i32 @test7(ptr %p) { ; CHECK-LABEL: define i32 @test7 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG3:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG5:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -95,7 +95,7 @@ define i32 @test8(ptr %p) { ; CHECK-LABEL: define i32 @test8 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG4:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -105,6 +105,31 @@ ret i32 %c } +define i32 @load_noundef_load(ptr %p) { +; CHECK-LABEL: define i32 @load_noundef_load +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]], !noundef !6 +; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] +; CHECK-NEXT: ret i32 [[C]] +; + %a = load i32, ptr %p, !range !0, !noundef !11 + %b = load i32, ptr %p, !range !1 + %c = add i32 %a, %b + ret i32 %c +} + +define i32 @load_load_noundef(ptr %p) { +; CHECK-LABEL: define i32 @load_load_noundef +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1]] +; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] +; CHECK-NEXT: ret i32 [[C]] +; + %a = load i32, ptr %p, !range !0 + %b = load i32, ptr %p, !range !1, !noundef !11 + %c = add i32 %a, %b + ret i32 %c +} !0 = !{i32 0, i32 2} !1 = !{i32 3, i32 5} @@ -117,10 +142,13 @@ !8 = !{i32 5, i32 1} !9 = !{i32 1, i32 5} !10 = !{i32 5, i32 1} +!11 = !{} ;. ; CHECK: [[RNG0]] = !{i32 0, i32 2} -; CHECK: [[RNG1]] = !{i32 -5, i32 -2} -; CHECK: [[RNG2]] = !{i32 10, i32 1} -; CHECK: [[RNG3]] = !{i32 1, i32 2, i32 3, i32 4} -; CHECK: [[RNG4]] = !{i32 1, i32 5} +; CHECK: [[RNG1]] = !{i32 0, i32 2, i32 3, i32 5} +; CHECK: [[RNG2]] = !{i32 0, i32 5} +; CHECK: [[RNG3]] = !{i32 -5, i32 -2, i32 1, i32 5} +; CHECK: [[RNG4]] = !{i32 10, i32 1} +; CHECK: [[RNG5]] = !{i32 3, i32 4, i32 5, i32 2} +; CHECK: [[META6:![0-9]+]] = !{} ;. diff --git a/llvm/test/Transforms/JumpThreading/thread-loads.ll b/llvm/test/Transforms/JumpThreading/thread-loads.ll --- a/llvm/test/Transforms/JumpThreading/thread-loads.ll +++ b/llvm/test/Transforms/JumpThreading/thread-loads.ll @@ -322,12 +322,12 @@ define void @test8(ptr, ptr, ptr) { ; CHECK-LABEL: @test8( ; CHECK-NEXT: ret2: -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP0:%.*]], align 4, !range [[RNG4:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP0:%.*]], align 4, !range [[RNG4:![0-9]+]], !noundef !5 ; CHECK-NEXT: store i32 [[A]], ptr [[TMP1:%.*]], align 4 ; CHECK-NEXT: [[XXX:%.*]] = tail call i32 (...) @f1() #[[ATTR0]] ; CHECK-NEXT: ret void ; - %a = load i32, ptr %0, !tbaa !0, !range !4, !alias.scope !9, !noalias !10 + %a = load i32, ptr %0, !tbaa !0, !range !4, !alias.scope !9, !noalias !10, !noundef !11 %b = load i32, ptr %0, !range !5 store i32 %a, ptr %1 %c = icmp eq i32 %b, 8 @@ -693,3 +693,4 @@ !8 = !{!8, !6} !9 = !{!7} !10 = !{!8} +!11 = !{} diff --git a/llvm/test/Transforms/NewGVN/range.ll b/llvm/test/Transforms/NewGVN/range.ll --- a/llvm/test/Transforms/NewGVN/range.ll +++ b/llvm/test/Transforms/NewGVN/range.ll @@ -17,7 +17,7 @@ define i32 @test2(ptr %p) { ; CHECK-LABEL: define i32 @test2 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -30,7 +30,7 @@ define i32 @test3(ptr %p) { ; CHECK-LABEL: define i32 @test3 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -43,7 +43,7 @@ define i32 @test4(ptr %p) { ; CHECK-LABEL: define i32 @test4 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG2:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -56,7 +56,7 @@ define i32 @test5(ptr %p) { ; CHECK-LABEL: define i32 @test5 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG3:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -69,7 +69,7 @@ define i32 @test6(ptr %p) { ; CHECK-LABEL: define i32 @test6 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG2:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG4:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -82,7 +82,7 @@ define i32 @test7(ptr %p) { ; CHECK-LABEL: define i32 @test7 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG3:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG5:![0-9]+]] ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -95,7 +95,7 @@ define i32 @test8(ptr %p) { ; CHECK-LABEL: define i32 @test8 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG4:![0-9]+]] +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]] ; CHECK-NEXT: ret i32 [[C]] ; @@ -119,8 +119,9 @@ !10 = !{i32 5, i32 1} ;. ; CHECK: [[RNG0]] = !{i32 0, i32 2} -; CHECK: [[RNG1]] = !{i32 -5, i32 -2} -; CHECK: [[RNG2]] = !{i32 10, i32 1} -; CHECK: [[RNG3]] = !{i32 1, i32 2, i32 3, i32 4} -; CHECK: [[RNG4]] = !{i32 1, i32 5} +; CHECK: [[RNG1]] = !{i32 0, i32 2, i32 3, i32 5} +; CHECK: [[RNG2]] = !{i32 0, i32 5} +; CHECK: [[RNG3]] = !{i32 -5, i32 -2, i32 1, i32 5} +; CHECK: [[RNG4]] = !{i32 10, i32 1} +; CHECK: [[RNG5]] = !{i32 3, i32 4, i32 5, i32 2} ;.