K->setMetadata(Kind, MDNode::intersect(JMD, KMD));
break;
case LLVMContext::MD_range:
- K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD));
+
+ // 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.
+ K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD));
break;
case LLVMContext::MD_fpmath:
K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD));
define i32 @test1(i32* %p) {
; CHECK-LABEL: @test1(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range !0
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p, !range !0
define i32 @test2(i32* %p) {
; CHECK-LABEL: @test2(i32* %p)
-; CHECK: %a = load i32, i32* %p
-; CHECK-NOT: range
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p
define i32 @test3(i32* %p) {
; CHECK-LABEL: @test3(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[DISJOINT_RANGE:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p, !range !1
define i32 @test4(i32* %p) {
; CHECK-LABEL: @test4(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_RANGE:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p, !range !2
define i32 @test5(i32* %p) {
; CHECK-LABEL: @test5(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_SIGNED_RANGE:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE3:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !3
%b = load i32, i32* %p, !range !4
define i32 @test6(i32* %p) {
; CHECK-LABEL: @test6(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_TEST6:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE5:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !5
%b = load i32, i32* %p, !range !6
define i32 @test7(i32* %p) {
; CHECK-LABEL: @test7(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_TEST7:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE7:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !7
%b = load i32, i32* %p, !range !8
define i32 @test8(i32* %p) {
; CHECK-LABEL: @test8(i32* %p)
-; CHECK: %a = load i32, i32* %p
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE9:[0-9]+]]
; CHECK-NOT: range
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !9
ret i32 %c
}
-; CHECK: ![[DISJOINT_RANGE]] = !{i32 0, i32 2, i32 3, i32 5}
-; CHECK: ![[MERGED_RANGE]] = !{i32 0, i32 5}
-; CHECK: ![[MERGED_SIGNED_RANGE]] = !{i32 -5, i32 -2, i32 1, i32 5}
-; CHECK: ![[MERGED_TEST6]] = !{i32 10, i32 1}
-; CHECK: ![[MERGED_TEST7]] = !{i32 3, i32 4, i32 5, i32 2}
+; CHECK: ![[RANGE0]] = !{i32 0, i32 2}
+; CHECK: ![[RANGE3]] = !{i32 -5, i32 -2}
+; CHECK: ![[RANGE5]] = !{i32 10, i32 1}
+; CHECK: ![[RANGE7]] = !{i32 1, i32 2, i32 3, i32 4}
+; CHECK: ![[RANGE9]] = !{i32 1, i32 5}
!0 = !{i32 0, i32 2}
!1 = !{i32 3, i32 5}
ret void
}
-; CHECK: ![[RANGE]] = !{i32 0, i32 5, i32 7, i32 9}
+; CHECK: ![[RANGE]] = !{i32 0, i32 5}
!0 = !{ i32 0, i32 5 }
!1 = !{ i32 7, i32 9 }
!2 = !{!2}
ret i32 %res.0
}
-; Make sure we merge the aliasing metadata. (If we don't, we have a load
-; with the wrong metadata, so the branch gets incorrectly eliminated.)
+; Make sure we merge the aliasing metadata. We keep the range metadata for the
+; first load, as it dominates the second load. Hence we can eliminate the
+; branch.
define void @test8(i32*, i32*, i32*) {
; CHECK-LABEL: @test8(
-; CHECK: %a = load i32, i32* %0, !range !4
+; CHECK: %a = load i32, i32* %0, !range ![[RANGE4:[0-9]+]]
; CHECK-NEXT: store i32 %a
-; CHECK: br i1 %c
+; CHECK-NEXT: %xxx = tail call i32 (...) @f1()
+; CHECK-NEXT: ret void
%a = load i32, i32* %0, !tbaa !0, !range !4, !alias.scope !9, !noalias !10
%b = load i32, i32* %0, !range !5
store i32 %a, i32* %1
ret i32 10
}
+; CHECK: ![[RANGE4]] = !{i32 0, i32 1}
+
!0 = !{!3, !3, i64 0}
!1 = !{!"omnipotent char", !2}
!2 = !{!"Simple C/C++ TBAA"}
define i32 @test1(i32* %p) {
; CHECK-LABEL: @test1(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range !0
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p, !range !0
define i32 @test2(i32* %p) {
; CHECK-LABEL: @test2(i32* %p)
-; CHECK: %a = load i32, i32* %p
-; CHECK-NOT: range
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p
define i32 @test3(i32* %p) {
; CHECK-LABEL: @test3(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[DISJOINT_RANGE:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p, !range !1
define i32 @test4(i32* %p) {
; CHECK-LABEL: @test4(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_RANGE:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE0]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !0
%b = load i32, i32* %p, !range !2
define i32 @test5(i32* %p) {
; CHECK-LABEL: @test5(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_SIGNED_RANGE:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE3:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !3
%b = load i32, i32* %p, !range !4
define i32 @test6(i32* %p) {
; CHECK-LABEL: @test6(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_TEST6:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE5:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !5
%b = load i32, i32* %p, !range !6
define i32 @test7(i32* %p) {
; CHECK-LABEL: @test7(i32* %p)
-; CHECK: %a = load i32, i32* %p, !range ![[MERGED_TEST7:[0-9]+]]
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE7:[0-9]+]]
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !7
%b = load i32, i32* %p, !range !8
define i32 @test8(i32* %p) {
; CHECK-LABEL: @test8(i32* %p)
-; CHECK: %a = load i32, i32* %p
+; CHECK: %a = load i32, i32* %p, !range ![[RANGE9:[0-9]+]]
; CHECK-NOT: range
; CHECK: %c = add i32 %a, %a
%a = load i32, i32* %p, !range !9
ret i32 %c
}
-; CHECK: ![[DISJOINT_RANGE]] = !{i32 0, i32 2, i32 3, i32 5}
-; CHECK: ![[MERGED_RANGE]] = !{i32 0, i32 5}
-; CHECK: ![[MERGED_SIGNED_RANGE]] = !{i32 -5, i32 -2, i32 1, i32 5}
-; CHECK: ![[MERGED_TEST6]] = !{i32 10, i32 1}
-; CHECK: ![[MERGED_TEST7]] = !{i32 3, i32 4, i32 5, i32 2}
+; CHECK: ![[RANGE0]] = !{i32 0, i32 2}
+; CHECK: ![[RANGE3]] = !{i32 -5, i32 -2}
+; CHECK: ![[RANGE5]] = !{i32 10, i32 1}
+; CHECK: ![[RANGE7]] = !{i32 1, i32 2, i32 3, i32 4}
+; CHECK: ![[RANGE9]] = !{i32 1, i32 5}
!0 = !{i32 0, i32 2}
!1 = !{i32 3, i32 5}