blob: c1ae371d79cf7982ee468daceb54e60c80c7b0c3 [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes=aggressive-instcombine -S < %s | FileCheck %s
declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
declare void @llvm.assume(i1)
define void @range_0_1(ptr %dst, i8 %value, i64 %n) !prof !0 {
; CHECK-LABEL: define void @range_0_1(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) !prof [[PROF0:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = and i64 [[N]], 1
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[DO_MEMSET:.*]], label %[[END:.*]], !prof [[PROF1:![0-9]+]]
; CHECK: [[DO_MEMSET]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[END]]
; CHECK: [[END]]:
; CHECK-NEXT: ret void
;
entry:
%len = and i64 %n, 1
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false)
ret void
}
define void @range_0_1_value_profile(ptr %dst, i8 %value, i64 %n) !prof !0 {
; CHECK-LABEL: define void @range_0_1_value_profile(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = and i64 [[N]], 1
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[BB0:.*]], label %[[BB1:.*]], !prof [[PROF2:![0-9]+]]
; CHECK: [[BB0]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[BB1]]
; CHECK: [[BB1]]:
; CHECK-NEXT: ret void
;
entry:
%len = and i64 %n, 1
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false), !prof !1
ret void
}
define void @range_0_1_value_profile_one_value(ptr %dst, i8 %value, i64 %n) !prof !0 {
; CHECK-LABEL: define void @range_0_1_value_profile_one_value(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = and i64 [[N]], 1
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[BB0:.*]], label %[[BB1:.*]], !prof [[PROF3:![0-9]+]]
; CHECK: [[BB0]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[BB1]]
; CHECK: [[BB1]]:
; CHECK-NEXT: ret void
;
entry:
%len = and i64 %n, 1
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false), !prof !2
ret void
}
define void @range_0_1_value_profile_invalid_values(ptr %dst, i8 %value, i64 %n) !prof !0 {
; CHECK-LABEL: define void @range_0_1_value_profile_invalid_values(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = and i64 [[N]], 1
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[BB0:.*]], label %[[BB1:.*]], !prof [[PROF1]]
; CHECK: [[BB0]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[BB1]]
; CHECK: [[BB1]]:
; CHECK-NEXT: ret void
;
entry:
%len = and i64 %n, 1
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false), !prof !3
ret void
}
define void @range_0_1_value_profile_double_zero(ptr %dst, i8 %value, i64 %n) !prof !0 {
; CHECK-LABEL: define void @range_0_1_value_profile_double_zero(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = and i64 [[N]], 1
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[BB0:.*]], label %[[BB1:.*]], !prof [[PROF1]]
; CHECK: [[BB0]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[BB1]]
; CHECK: [[BB1]]:
; CHECK-NEXT: ret void
;
entry:
%len = and i64 %n, 1
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false), !prof !4
ret void
}
define void @range_0_1_zext(ptr %dst, i8 %value, i32 %n) {
; CHECK-LABEL: define void @range_0_1_zext(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[N]], 1
; CHECK-NEXT: [[LEN:%.*]] = zext i32 [[MASKED]] to i64
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[DO_MEMSET:.*]], label %[[END:.*]]
; CHECK: [[DO_MEMSET]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[END]]
; CHECK: [[END]]:
; CHECK-NEXT: ret void
;
entry:
%masked = and i32 %n, 1
%len = zext i32 %masked to i64
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false)
ret void
}
define void @range_0_1_assume(ptr %dst, i8 %value, i64 %n) {
; CHECK-LABEL: define void @range_0_1_assume(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[IN_RANGE:%.*]] = icmp ule i64 [[N]], 1
; CHECK-NEXT: call void @llvm.assume(i1 [[IN_RANGE]])
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[N]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[DO_MEMSET:.*]], label %[[END:.*]]
; CHECK: [[DO_MEMSET]]:
; CHECK-NEXT: store i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[END]]
; CHECK: [[END]]:
; CHECK-NEXT: ret void
;
entry:
%in.range = icmp ule i64 %n, 1
call void @llvm.assume(i1 %in.range)
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %n, i1 false)
ret void
}
define void @range_0_1_volatile(ptr %dst, i8 %value, i64 %n) {
; CHECK-LABEL: define void @range_0_1_volatile(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = and i64 [[N]], 1
; CHECK-NEXT: [[MEMSET_NOTZERO:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: br i1 [[MEMSET_NOTZERO]], label %[[DO_MEMSET:.*]], label %[[END:.*]]
; CHECK: [[DO_MEMSET]]:
; CHECK-NEXT: store volatile i8 [[VALUE]], ptr [[DST]], align 1
; CHECK-NEXT: br label %[[END]]
; CHECK: [[END]]:
; CHECK-NEXT: ret void
;
entry:
%len = and i64 %n, 1
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 true)
ret void
}
define void @range_0_2(ptr %dst, i8 %value, i64 %n) {
; CHECK-LABEL: define void @range_0_2(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LEN:%.*]] = urem i64 [[N]], 3
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 [[VALUE]], i64 [[LEN]], i1 false)
; CHECK-NEXT: ret void
;
entry:
%len = urem i64 %n, 3
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %len, i1 false)
ret void
}
define void @unknown_length(ptr %dst, i8 %value, i64 %n) {
; CHECK-LABEL: define void @unknown_length(
; CHECK-SAME: ptr [[DST:%.*]], i8 [[VALUE:%.*]], i64 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 [[VALUE]], i64 [[N]], i1 false)
; CHECK-NEXT: ret void
;
entry:
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 %value, i64 %n, i1 false)
ret void
}
!0 = !{!"function_entry_count", i32 10}
!1 = !{!"VP", i32 1, i64 5, i64 0, i64 2, i64 1, i64 3}
!2 = !{!"VP", i32 1, i64 5, i64 1, i64 5}
!3 = !{!"VP", i32 1, i64 5, i64 2, i64 4, i64 3, i64 1}
!4 = !{!"VP", i32 1, i64 5, i64 0, i64 0, i64 1, i64 0}
;.
; CHECK: [[PROF0]] = !{!"function_entry_count", i32 10}
; CHECK: [[PROF1]] = !{!"unknown", !"aggressive-instcombine"}
; CHECK: [[PROF2]] = !{!"branch_weights", i32 3, i32 2}
; CHECK: [[PROF3]] = !{!"branch_weights", i32 5, i32 0}
;.