; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --version 2
; RUN: opt -passes=gvn -S < %s | FileCheck %s
+declare void @use.ptr(ptr)
+declare void @use.i64(i64)
+declare void @use.i32(i32)
+
define i32 @test1(ptr %p) {
; CHECK-LABEL: define i32 @test1
; CHECK-SAME: (ptr [[P:%.*]]) {
ret i32 %c
}
-declare void @use.i64(i64)
-declare void @use.i32(i32)
+define void @load_dereferenceable_dominating(ptr %p) {
+; CHECK-LABEL: define void @load_dereferenceable_dominating
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 8
+; CHECK-NEXT: call void @use.ptr(ptr [[A]])
+; CHECK-NEXT: call void @use.ptr(ptr [[A]])
+; CHECK-NEXT: ret void
+;
+ %a = load ptr, ptr %p, !dereferenceable !{i64 10}
+ %b = load ptr, ptr %p
+ call void @use.ptr(ptr %a)
+ call void @use.ptr(ptr %b)
+ ret void
+}
+
+define void @load_dereferenceable_not_dominating(ptr %p) {
+; CHECK-LABEL: define void @load_dereferenceable_not_dominating
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 8
+; CHECK-NEXT: call void @use.ptr(ptr [[A]])
+; CHECK-NEXT: call void @use.ptr(ptr [[A]])
+; CHECK-NEXT: ret void
+;
+ %a = load ptr, ptr %p
+ %b = load ptr, ptr %p, !dereferenceable !{i64 10}
+ call void @use.ptr(ptr %a)
+ call void @use.ptr(ptr %b)
+ ret void
+}
define void @load_ptr_nonnull_to_i64(ptr %p) {
; CHECK-LABEL: define void @load_ptr_nonnull_to_i64
ret void
}
+define void @load_ptr_dereferenceable_to_i64(ptr %p) {
+; CHECK-LABEL: define void @load_ptr_dereferenceable_to_i64
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[VAL:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !7
+; CHECK-NEXT: [[VAL_INT:%.*]] = ptrtoint ptr [[VAL]] to i64
+; CHECK-NEXT: call void @use.i64(i64 [[VAL_INT]])
+; CHECK-NEXT: call void @use.i64(i64 [[VAL_INT]])
+; CHECK-NEXT: ret void
+;
+ %val = load ptr, ptr %p, align 8, !dereferenceable !{i64 10}
+ %val.int = ptrtoint ptr %val to i64
+ %val2 = load i64, ptr %p, align 8
+ call void @use.i64(i64 %val.int)
+ call void @use.i64(i64 %val2)
+ ret void
+}
+
+define void @load_ptr_dereferenceable_or_null_to_i64(ptr %p) {
+; CHECK-LABEL: define void @load_ptr_dereferenceable_or_null_to_i64
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[VAL:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable_or_null !7
+; CHECK-NEXT: [[VAL_INT:%.*]] = ptrtoint ptr [[VAL]] to i64
+; CHECK-NEXT: call void @use.i64(i64 [[VAL_INT]])
+; CHECK-NEXT: call void @use.i64(i64 [[VAL_INT]])
+; CHECK-NEXT: ret void
+;
+ %val = load ptr, ptr %p, align 8, !dereferenceable_or_null !{i64 10}
+ %val.int = ptrtoint ptr %val to i64
+ %val2 = load i64, ptr %p, align 8
+ call void @use.i64(i64 %val.int)
+ call void @use.i64(i64 %val2)
+ ret void
+}
+
define void @load_ptr_nonnull_to_i32(ptr %p) {
; CHECK-LABEL: define void @load_ptr_nonnull_to_i32
; CHECK-SAME: (ptr [[P:%.*]]) {
define void @load_i64_range_to_i32_range(ptr %p) {
; CHECK-LABEL: define void @load_i64_range_to_i32_range
; CHECK-SAME: (ptr [[P:%.*]]) {
-; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[P]], align 8, !range [[RNG7:![0-9]+]]
+; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[P]], align 8, !range [[RNG8:![0-9]+]]
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[VAL]] to i32
; CHECK-NEXT: call void @use.i64(i64 [[VAL]])
; CHECK-NEXT: call void @use.i32(i32 [[TMP1]])
; CHECK: [[RNG4]] = !{i32 10, i32 1}
; CHECK: [[RNG5]] = !{i32 3, i32 4, i32 5, i32 2}
; CHECK: [[META6:![0-9]+]] = !{}
-; CHECK: [[RNG7]] = !{i64 0, i64 10}
+; CHECK: [[META7:![0-9]+]] = !{i64 10}
+; CHECK: [[RNG8]] = !{i64 0, i64 10}
;.
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -hoist-common-insts=true -S | FileCheck %s
-define void @foo(i1 %c, ptr %p) {
-; CHECK-LABEL: @foo(
+define void @hoist_range(i1 %c, ptr %p) {
+; CHECK-LABEL: @hoist_range(
; CHECK-NEXT: if:
; CHECK-NEXT: [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !range [[RNG0:![0-9]+]]
; CHECK-NEXT: ret void
ret void
}
-define void @md_noundef_combine(i1 %c, ptr %p) {
-; CHECK-LABEL: @md_noundef_combine(
+define void @hoist_both_noundef(i1 %c, ptr %p) {
+; CHECK-LABEL: @hoist_both_noundef(
; CHECK-NEXT: if:
; CHECK-NEXT: [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !1
; CHECK-NEXT: ret void
ret void
}
-define void @md_noundef_dont_combine(i1 %c, ptr %p) {
-; CHECK-LABEL: @md_noundef_dont_combine(
+define void @hoist_one_noundef(i1 %c, ptr %p) {
+; CHECK-LABEL: @hoist_one_noundef(
; CHECK-NEXT: if:
; CHECK-NEXT: [[T:%.*]] = load i8, ptr [[P:%.*]], align 1
; CHECK-NEXT: ret void
ret void
}
+define void @hoist_dereferenceable(i1 %c, ptr %p) {
+; CHECK-LABEL: @hoist_dereferenceable(
+; CHECK-NEXT: if:
+; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !2
+; CHECK-NEXT: ret void
+;
+if:
+ br i1 %c, label %then, label %else
+then:
+ %t = load ptr, ptr %p, !dereferenceable !{i64 10}
+ br label %out
+else:
+ %e = load ptr, ptr %p, !dereferenceable !{i64 20}
+ br label %out
+out:
+ ret void
+}
+
+define void @hoist_dereferenceable_or_null(i1 %c, ptr %p) {
+; CHECK-LABEL: @hoist_dereferenceable_or_null(
+; CHECK-NEXT: if:
+; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null !2
+; CHECK-NEXT: ret void
+;
+if:
+ br i1 %c, label %then, label %else
+then:
+ %t = load ptr, ptr %p, !dereferenceable_or_null !{i64 20}
+ br label %out
+else:
+ %e = load ptr, ptr %p, !dereferenceable_or_null !{i64 10}
+ br label %out
+out:
+ ret void
+}
+
define i32 @speculate_range(i1 %c, ptr dereferenceable(8) align 8 %p) {
; CHECK-LABEL: @speculate_range(
; CHECK-NEXT: entry:
define void @hoist_fpmath(i1 %c, double %x) {
; CHECK-LABEL: @hoist_fpmath(
; CHECK-NEXT: if:
-; CHECK-NEXT: [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !2
+; CHECK-NEXT: [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !3
; CHECK-NEXT: ret void
;
if:
;.
; CHECK: [[RNG0]] = !{i8 0, i8 1, i8 3, i8 5}
; CHECK: [[META1:![0-9]+]] = !{}
-; CHECK: [[META2:![0-9]+]] = !{float 2.500000e+00}
+; CHECK: [[META2:![0-9]+]] = !{i64 10}
+; CHECK: [[META3:![0-9]+]] = !{float 2.500000e+00}
;.