blob: 611d607ca7ebcad5f31f82e65c7ef9e1c283e5f3 [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes='drop-unnecessary-assumes' -S %s | FileCheck %s
; RUN: opt -passes='drop-unnecessary-assumes<drop-deref>' -S %s | FileCheck --check-prefix=DROP-DEREF %s
declare void @use(ptr)
define i8 @test_dereferenceable_assume_ptr_not_used(ptr %p, i64 %size) {
; CHECK-LABEL: define i8 @test_dereferenceable_assume_ptr_not_used(
; CHECK-SAME: ptr [[P:%.*]], i64 [[SIZE:%.*]]) {
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[SIZE]]) ]
; CHECK-NEXT: ret i8 0
;
; DROP-DEREF-LABEL: define i8 @test_dereferenceable_assume_ptr_not_used(
; DROP-DEREF-SAME: ptr [[P:%.*]], i64 [[SIZE:%.*]]) {
; DROP-DEREF-NEXT: ret i8 0
;
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 %size) ]
ret i8 0
}
define i8 @test_dereferenceable_assume_ptr_used_variable_size(ptr %p, i64 %size) {
; CHECK-LABEL: define i8 @test_dereferenceable_assume_ptr_used_variable_size(
; CHECK-SAME: ptr [[P:%.*]], i64 [[SIZE:%.*]]) {
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[SIZE]]) ]
; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: ret i8 [[VAL]]
;
; DROP-DEREF-LABEL: define i8 @test_dereferenceable_assume_ptr_used_variable_size(
; DROP-DEREF-SAME: ptr [[P:%.*]], i64 [[SIZE:%.*]]) {
; DROP-DEREF-NEXT: [[VAL:%.*]] = load i8, ptr [[P]], align 1
; DROP-DEREF-NEXT: ret i8 [[VAL]]
;
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 %size) ]
%val = load i8, ptr %p
ret i8 %val
}
define i8 @test_dereferenceable_with_align_ptr_used(ptr %p, i64 %size) {
; CHECK-LABEL: define i8 @test_dereferenceable_with_align_ptr_used(
; CHECK-SAME: ptr [[P:%.*]], i64 [[SIZE:%.*]]) {
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[SIZE]]), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: ret i8 [[VAL]]
;
; DROP-DEREF-LABEL: define i8 @test_dereferenceable_with_align_ptr_used(
; DROP-DEREF-SAME: ptr [[P:%.*]], i64 [[SIZE:%.*]]) {
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: [[VAL:%.*]] = load i8, ptr [[P]], align 1
; DROP-DEREF-NEXT: ret i8 [[VAL]]
;
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 %size), "align"(ptr %p, i64 8) ]
%val = load i8, ptr %p
ret i8 %val
}
; Regression test for AssumptionCache::removeAffectedValues() crash revealed at
; (but not caused by) def1355cf14cec28f71b8ca947b7723641c1580d
;
; Check that when the first AssumeInst has two op bundles that rely on %arg1,
; removeAffectedValues() is not confused by the presence of an unrelated
; AssumeInst that also has an %arg1 op bundle.
define ptr @test_dup_ptr_used_elsewhere(i1 %arg, ptr %arg1) {
; CHECK-LABEL: define ptr @test_dup_ptr_used_elsewhere(
; CHECK-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: br i1 [[ARG]], label %[[BB3:.*]], label %[[BB4:.*]]
; CHECK: [[BB2:.*]]:
; CHECK-NEXT: ret ptr null
; CHECK: [[BB3]]:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 1) ]
; CHECK-NEXT: br label %[[BB2]]
; CHECK: [[BB4]]:
; CHECK-NEXT: br label %[[BB2]]
;
; DROP-DEREF-LABEL: define ptr @test_dup_ptr_used_elsewhere(
; DROP-DEREF-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]]) {
; DROP-DEREF-NEXT: [[BB:.*:]]
; DROP-DEREF-NEXT: br i1 [[ARG]], label %[[BB3:.*]], label %[[BB4:.*]]
; DROP-DEREF: [[BB2:.*]]:
; DROP-DEREF-NEXT: ret ptr null
; DROP-DEREF: [[BB3]]:
; DROP-DEREF-NEXT: br label %[[BB2]]
; DROP-DEREF: [[BB4]]:
; DROP-DEREF-NEXT: br label %[[BB2]]
;
bbl:
br i1 %arg, label %bbl3, label %bbl4
bbl2:
ret ptr null
bbl3:
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %arg1, i64 1), "align"(ptr %arg1, i64 8) ]
br label %bbl2
bbl4:
call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4) ]
br label %bbl2
}
; @test_dup_ptr_used_elsewhere with extra ptr
define ptr @test_dup_ptr_used_elsewhere_extra(i1 %arg, ptr %arg1, ptr %arg2) {
; CHECK-LABEL: define ptr @test_dup_ptr_used_elsewhere_extra(
; CHECK-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
; CHECK-NEXT: [[BBL:.*:]]
; CHECK-NEXT: br i1 [[ARG]], label %[[BBL3:.*]], label %[[BBL4:.*]]
; CHECK: [[BBL2:.*]]:
; CHECK-NEXT: ret ptr null
; CHECK: [[BBL3]]:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 1), "dereferenceable"(ptr [[ARG2]], i64 1) ]
; CHECK-NEXT: br label %[[BBL2]]
; CHECK: [[BBL4]]:
; CHECK-NEXT: br label %[[BBL2]]
;
; DROP-DEREF-LABEL: define ptr @test_dup_ptr_used_elsewhere_extra(
; DROP-DEREF-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
; DROP-DEREF-NEXT: [[BBL:.*:]]
; DROP-DEREF-NEXT: br i1 [[ARG]], label %[[BBL3:.*]], label %[[BBL4:.*]]
; DROP-DEREF: [[BBL2:.*]]:
; DROP-DEREF-NEXT: ret ptr null
; DROP-DEREF: [[BBL3]]:
; DROP-DEREF-NEXT: br label %[[BBL2]]
; DROP-DEREF: [[BBL4]]:
; DROP-DEREF-NEXT: br label %[[BBL2]]
;
bbl:
br i1 %arg, label %bbl3, label %bbl4
bbl2:
ret ptr null
bbl3:
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %arg1, i64 1), "align"(ptr %arg1, i64 8),
"dereferenceable"(ptr %arg2, i64 1), "align"(ptr %arg2, i64 8) ]
br label %bbl2
bbl4:
call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4), "align"(ptr %arg2, i64 4) ]
br label %bbl2
}
; @test_dup_ptr_used_elsewhere_extra with even more op bundles
define ptr @test_dup_ptr_used_elsewhere_extra2(i1 %arg, ptr %arg1, ptr %arg2) {
; CHECK-LABEL: define ptr @test_dup_ptr_used_elsewhere_extra2(
; CHECK-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
; CHECK-NEXT: [[BBL:.*:]]
; CHECK-NEXT: br i1 [[ARG]], label %[[BBL3:.*]], label %[[BBL4:.*]]
; CHECK: [[BBL2:.*]]:
; CHECK-NEXT: ret ptr null
; CHECK: [[BBL3]]:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 1), "dereferenceable"(ptr [[ARG2]], i64 1), "dereferenceable"(ptr [[ARG1]], i64 1), "dereferenceable"(ptr [[ARG2]], i64 1), "dereferenceable"(ptr [[ARG1]], i64 1) ]
; CHECK-NEXT: br label %[[BBL2]]
; CHECK: [[BBL4]]:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 1), "dereferenceable"(ptr [[ARG2]], i64 1) ]
; CHECK-NEXT: br label %[[BBL2]]
;
; DROP-DEREF-LABEL: define ptr @test_dup_ptr_used_elsewhere_extra2(
; DROP-DEREF-SAME: i1 [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
; DROP-DEREF-NEXT: [[BBL:.*:]]
; DROP-DEREF-NEXT: br i1 [[ARG]], label %[[BBL3:.*]], label %[[BBL4:.*]]
; DROP-DEREF: [[BBL2:.*]]:
; DROP-DEREF-NEXT: ret ptr null
; DROP-DEREF: [[BBL3]]:
; DROP-DEREF-NEXT: br label %[[BBL2]]
; DROP-DEREF: [[BBL4]]:
; DROP-DEREF-NEXT: br label %[[BBL2]]
;
bbl:
br i1 %arg, label %bbl3, label %bbl4
bbl2:
ret ptr null
bbl3:
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %arg1, i64 1), "align"(ptr %arg2, i64 8),
"dereferenceable"(ptr %arg2, i64 1), "dereferenceable"(ptr %arg1, i64 1),
"dereferenceable"(ptr %arg2, i64 1), "dereferenceable"(ptr %arg1, i64 1) ]
br label %bbl2
bbl4:
call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4), "align"(ptr %arg2, i64 4),
"dereferenceable"(ptr %arg1, i64 1), "dereferenceable"(ptr %arg2, i64 1) ]
br label %bbl2
}
; Make sure newly created assumes are handled properly.
define i8 @test_dereferenceable_with_align_cache_realloc(ptr %p, ptr %q, i1 %c) {
; CHECK-LABEL: define i8 @test_dereferenceable_with_align_cache_realloc(
; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]]) {
; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q]], i64 8), "align"(ptr [[P]], i64 8) ]
; CHECK-NEXT: ret i8 [[V]]
;
; DROP-DEREF-LABEL: define i8 @test_dereferenceable_with_align_cache_realloc(
; DROP-DEREF-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]]) {
; DROP-DEREF-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
; DROP-DEREF-NEXT: ret i8 [[V]]
;
%v = load i8, ptr %p
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %q, i64 8), "align"(ptr %p, i64 8) ]
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
call void @llvm.assume(i1 %c)
ret i8 %v
}