188 lines
5.8 KiB
LLVM
188 lines
5.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
; Passing select(cond, null, v) as nonnull should be optimized to passing v
|
|
|
|
define nonnull ptr @pr48975(ptr %.0) {
|
|
; CHECK-LABEL: @pr48975(
|
|
; CHECK-NEXT: ret ptr [[DOT4:%.*]]
|
|
;
|
|
%.1 = load ptr, ptr %.0, align 8
|
|
%.2 = icmp eq ptr %.1, null
|
|
%.4 = select i1 %.2, ptr null, ptr %.0
|
|
ret ptr %.4
|
|
}
|
|
|
|
define nonnull ptr @nonnull_ret(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_ret(
|
|
; CHECK-NEXT: ret ptr [[RES:%.*]]
|
|
;
|
|
%res = select i1 %cond, ptr %p, ptr null
|
|
ret ptr %res
|
|
}
|
|
|
|
define nonnull ptr @nonnull_ret2(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_ret2(
|
|
; CHECK-NEXT: ret ptr [[RES:%.*]]
|
|
;
|
|
%res = select i1 %cond, ptr null, ptr %p
|
|
ret ptr %res
|
|
}
|
|
|
|
define nonnull noundef ptr @nonnull_noundef_ret(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_noundef_ret(
|
|
; CHECK-NEXT: ret ptr [[RES:%.*]]
|
|
;
|
|
%res = select i1 %cond, ptr %p, ptr null
|
|
ret ptr %res
|
|
}
|
|
|
|
define nonnull noundef ptr @nonnull_noundef_ret2(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_noundef_ret2(
|
|
; CHECK-NEXT: ret ptr [[RES:%.*]]
|
|
;
|
|
%res = select i1 %cond, ptr null, ptr %p
|
|
ret ptr %res
|
|
}
|
|
|
|
|
|
define void @nonnull_call(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_call(
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[RES:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%res = select i1 %cond, ptr %p, ptr null
|
|
call void @f(ptr nonnull %res)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_call2(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_call2(
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[RES:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%res = select i1 %cond, ptr null, ptr %p
|
|
call void @f(ptr nonnull %res)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_noundef_call(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_noundef_call(
|
|
; CHECK-NEXT: call void @f(ptr noundef nonnull [[RES:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%res = select i1 %cond, ptr %p, ptr null
|
|
call void @f(ptr nonnull noundef %res)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_noundef_call2(i1 %cond, ptr %p) {
|
|
; CHECK-LABEL: @nonnull_noundef_call2(
|
|
; CHECK-NEXT: call void @f(ptr noundef nonnull [[RES:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%res = select i1 %cond, ptr null, ptr %p
|
|
call void @f(ptr nonnull noundef %res)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_call_gep(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_call_gep(
|
|
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]]
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[GEP]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr i8, ptr %ptr, i64 %off
|
|
call void @f(ptr nonnull %gep)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_call_gep_multiuse(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_call_gep_multiuse(
|
|
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]]
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[GEP]])
|
|
; CHECK-NEXT: call void @f(ptr [[GEP]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr inbounds i8, ptr %ptr, i64 %off
|
|
call void @f(ptr nonnull %gep)
|
|
call void @f(ptr %gep)
|
|
ret void
|
|
}
|
|
|
|
define void @all_nonnull_call_gep_multiuse(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @all_nonnull_call_gep_multiuse(
|
|
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]]
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[GEP]])
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[GEP]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr inbounds i8, ptr %ptr, i64 %off
|
|
call void @f(ptr nonnull %gep)
|
|
call void @f(ptr nonnull %gep)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_call_gep_inbounds(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_call_gep_inbounds(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: call void @f(ptr nonnull [[GEP]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr inbounds i8, ptr %ptr, i64 %off
|
|
call void @f(ptr nonnull %gep)
|
|
ret void
|
|
}
|
|
|
|
define void @nonnull_dereferenceable_call_gep(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_dereferenceable_call_gep(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: call void @f(ptr dereferenceable(1) [[GEP]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr i8, ptr %ptr, i64 %off
|
|
call void @f(ptr dereferenceable(1) %gep)
|
|
ret void
|
|
}
|
|
|
|
define nonnull ptr @nonnull_ret_gep(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_ret_gep(
|
|
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]]
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: ret ptr [[GEP]]
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr i8, ptr %ptr, i64 %off
|
|
ret ptr %gep
|
|
}
|
|
|
|
define nonnull ptr @nonnull_ret_gep_inbounds(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_ret_gep_inbounds(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: ret ptr [[GEP]]
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr inbounds i8, ptr %ptr, i64 %off
|
|
ret ptr %gep
|
|
}
|
|
|
|
define dereferenceable(1) ptr @nonnull_dereferenceable_ret_gep(i1 %cond, ptr %p, i64 %off) {
|
|
; CHECK-LABEL: @nonnull_dereferenceable_ret_gep(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 [[OFF:%.*]]
|
|
; CHECK-NEXT: ret ptr [[GEP]]
|
|
;
|
|
%ptr = select i1 %cond, ptr null, ptr %p
|
|
%gep = getelementptr i8, ptr %ptr, i64 %off
|
|
ret ptr %gep
|
|
}
|
|
|
|
declare void @f(ptr)
|