blob: 15e81c53efc753abd753ec4bd779b9e437501fbc [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -aa-pipeline= -passes=dse -S %s | FileCheck %s
target datalayout = "p:64:64:64:8-p2:64:64:64:64"
; %k == %d + 1 due to wrapping, so the store to %d clobbers %k.
define i32 @wrap_not_redundant(ptr %b) {
; CHECK-LABEL: define i32 @wrap_not_redundant(
; CHECK-SAME: ptr [[B:%.*]]) {
; CHECK-NEXT: [[D:%.*]] = getelementptr i8, ptr [[B]], i8 127
; CHECK-NEXT: [[K:%.*]] = getelementptr i8, ptr [[B]], i8 -128
; CHECK-NEXT: store i32 1, ptr [[K]], align 1
; CHECK-NEXT: store i32 2, ptr [[D]], align 1
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[K]], align 1
; CHECK-NEXT: store i32 1, ptr [[K]], align 1
; CHECK-NEXT: ret i32 [[V]]
;
%d = getelementptr i8, ptr %b, i8 127
%k = getelementptr i8, ptr %b, i8 -128
store i32 1, ptr %k, align 1
store i32 2, ptr %d, align 1
%v = load i32, ptr %k, align 1
store i32 1, ptr %k, align 1
ret i32 %v
}
; The store to %k does not overwrite the first byte of the store to %d, which
; wraps around the end of the 64-bit index range.
define void @wrap_i64(ptr addrspace(2) %b) {
; CHECK-LABEL: define void @wrap_i64(
; CHECK-SAME: ptr addrspace(2) [[B:%.*]]) {
; CHECK-NEXT: [[D:%.*]] = getelementptr i8, ptr addrspace(2) [[B]], i64 9223372036854775807
; CHECK-NEXT: [[K:%.*]] = getelementptr i8, ptr addrspace(2) [[B]], i64 -9223372036854775808
; CHECK-NEXT: store i32 1, ptr addrspace(2) [[D]], align 1
; CHECK-NEXT: store i64 2, ptr addrspace(2) [[K]], align 1
; CHECK-NEXT: ret void
;
%d = getelementptr i8, ptr addrspace(2) %b, i64 9223372036854775807
%k = getelementptr i8, ptr addrspace(2) %b, i64 -9223372036854775808
store i32 1, ptr addrspace(2) %d, align 1
store i64 2, ptr addrspace(2) %k, align 1
ret void
}
; The store to %k (bytes 126 to -123) completely overwrites the store to %d.
define void @wrap_complete(ptr %b) {
; CHECK-LABEL: define void @wrap_complete(
; CHECK-SAME: ptr [[B:%.*]]) {
; CHECK-NEXT: [[K:%.*]] = getelementptr i8, ptr [[B]], i8 126
; CHECK-NEXT: store i64 2, ptr [[K]], align 1
; CHECK-NEXT: ret void
;
%d = getelementptr i8, ptr %b, i8 -128
%k = getelementptr i8, ptr %b, i8 126
store i32 1, ptr %d, align 1
store i64 2, ptr %k, align 1
ret void
}
; The memset (bytes 120 to -121) can be shortened at the end.
define void @shorten_end_wrap(ptr %b, i64 %x) {
; CHECK-LABEL: define void @shorten_end_wrap(
; CHECK-SAME: ptr [[B:%.*]], i64 [[X:%.*]]) {
; CHECK-NEXT: [[D:%.*]] = getelementptr i8, ptr [[B]], i8 120
; CHECK-NEXT: [[K:%.*]] = getelementptr i8, ptr [[B]], i8 -128
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[D]], i8 0, i64 8, i1 false)
; CHECK-NEXT: store i64 [[X]], ptr [[K]], align 1
; CHECK-NEXT: ret void
;
%d = getelementptr i8, ptr %b, i8 120
%k = getelementptr i8, ptr %b, i8 -128
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 16, i1 false)
store i64 %x, ptr %k, align 1
ret void
}
; The memset (bytes -128 to -113) can be shortened at the beginning.
define void @shorten_begin_wrap(ptr %b, i64 %x) {
; CHECK-LABEL: define void @shorten_begin_wrap(
; CHECK-SAME: ptr [[B:%.*]], i64 [[X:%.*]]) {
; CHECK-NEXT: [[D:%.*]] = getelementptr i8, ptr [[B]], i8 -128
; CHECK-NEXT: [[K:%.*]] = getelementptr i8, ptr [[B]], i8 126
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 6
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP1]], i8 0, i64 10, i1 false)
; CHECK-NEXT: store i64 [[X]], ptr [[K]], align 1
; CHECK-NEXT: ret void
;
%d = getelementptr i8, ptr %b, i8 -128
%k = getelementptr i8, ptr %b, i8 126
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 16, i1 false)
store i64 %x, ptr %k, align 1
ret void
}
; Pointers with different index widths are not analyzed.
define void @mixed_idx_width(ptr addrspace(2) %b) {
; CHECK-LABEL: define void @mixed_idx_width(
; CHECK-SAME: ptr addrspace(2) [[B:%.*]]) {
; CHECK-NEXT: [[C:%.*]] = addrspacecast ptr addrspace(2) [[B]] to ptr
; CHECK-NEXT: [[D:%.*]] = getelementptr i8, ptr [[C]], i8 1
; CHECK-NEXT: [[K:%.*]] = getelementptr i8, ptr addrspace(2) [[B]], i64 1000
; CHECK-NEXT: store i32 1, ptr [[D]], align 1
; CHECK-NEXT: store i32 2, ptr addrspace(2) [[K]], align 1
; CHECK-NEXT: ret void
;
%c = addrspacecast ptr addrspace(2) %b to ptr
%d = getelementptr i8, ptr %c, i8 1
%k = getelementptr i8, ptr addrspace(2) %b, i64 1000
store i32 1, ptr %d, align 1
store i32 2, ptr addrspace(2) %k, align 1
ret void
}