
Remove compares after replacing all uses. Cleaning dead compares can enable additional simplifications when adjusting the position of the pass slightly. In particular, it seems like the additional dead instructions may prevent SimplifyCFG performing some folds. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D158760
392 lines
20 KiB
LLVM
392 lines
20 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
|
|
|
|
declare void @llvm.assume(i1 noundef) #0
|
|
|
|
define i1 @gep_add_1_uge_inbounds(ptr %dst, ptr %lower) {
|
|
; CHECK-LABEL: @gep_add_1_uge_inbounds(
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 1
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
|
|
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 3
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%pre = icmp uge ptr %dst, %lower
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst, i64 1
|
|
%cmp.add.1 = icmp uge ptr %dst.add.1, %lower
|
|
%dst.add.2 = getelementptr inbounds i8, ptr %dst.add.1, i64 1
|
|
%cmp.add.3 = icmp uge ptr %dst.add.3, %lower
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.3
|
|
%dst.add.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 3
|
|
%cmp.add.4 = icmp uge ptr %dst.add.4, %lower
|
|
%res.2 = xor i1 %res.1, %cmp.add.4
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_uge_inbounds_scalable_vector(ptr %dst, ptr %lower) {
|
|
; CHECK-LABEL: @gep_add_1_uge_inbounds_scalable_vector(
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp uge ptr [[DST_ADD_1]], [[LOWER]]
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST_ADD_1]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_3:%.*]] = icmp uge ptr [[DST_ADD_3]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_3]]
|
|
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds <vscale x 4 x i8>, ptr [[DST_ADD_3]], i64 3
|
|
; CHECK-NEXT: [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%pre = icmp uge ptr %dst, %lower
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.3 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst, i64 3
|
|
%dst.add.1 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst, i64 1
|
|
%cmp.add.1 = icmp uge ptr %dst.add.1, %lower
|
|
%dst.add.2 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst.add.1, i64 1
|
|
%cmp.add.3 = icmp uge ptr %dst.add.3, %lower
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.3
|
|
%dst.add.4 = getelementptr inbounds <vscale x 4 x i8>, ptr %dst.add.3, i64 3
|
|
%cmp.add.4 = icmp uge ptr %dst.add.4, %lower
|
|
%res.2 = xor i1 %res.1, %cmp.add.4
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_uge_only_inner_inbounds(ptr %dst, ptr %lower) {
|
|
; CHECK-LABEL: @gep_add_1_uge_only_inner_inbounds(
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr i8, ptr [[DST_ADD_1]], i64 1
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
|
|
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 3
|
|
; CHECK-NEXT: [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%pre = icmp uge ptr %dst, %lower
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst, i64 1
|
|
%cmp.add.1 = icmp uge ptr %dst.add.1, %lower
|
|
%dst.add.2 = getelementptr i8, ptr %dst.add.1, i64 1
|
|
%cmp.add.3 = icmp uge ptr %dst.add.3, %lower
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.3
|
|
%dst.add.4 = getelementptr i8, ptr %dst.add.3, i64 3
|
|
%cmp.add.4 = icmp uge ptr %dst.add.4, %lower
|
|
%res.2 = xor i1 %res.1, %cmp.add.4
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_uge_only_outer_inbounds(ptr %dst, ptr %lower) {
|
|
; CHECK-LABEL: @gep_add_1_uge_only_outer_inbounds(
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr i8, ptr [[DST]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp uge ptr [[DST_ADD_1]], [[LOWER]]
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_3:%.*]] = icmp uge ptr [[DST_ADD_3]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_3]]
|
|
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 3
|
|
; CHECK-NEXT: [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%pre = icmp uge ptr %dst, %lower
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.3 = getelementptr i8, ptr %dst, i64 3
|
|
%dst.add.1 = getelementptr i8, ptr %dst, i64 1
|
|
%cmp.add.1 = icmp uge ptr %dst.add.1, %lower
|
|
%dst.add.2 = getelementptr inbounds i8, ptr %dst.add.1, i64 1
|
|
%cmp.add.3 = icmp uge ptr %dst.add.3, %lower
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.3
|
|
%dst.add.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 3
|
|
%cmp.add.4 = icmp uge ptr %dst.add.4, %lower
|
|
%res.2 = xor i1 %res.1, %cmp.add.4
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_uge_no_inbounds(ptr %dst, ptr %lower) {
|
|
; CHECK-LABEL: @gep_add_1_uge_no_inbounds(
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr i8, ptr [[DST]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp uge ptr [[DST_ADD_1]], [[LOWER]]
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr i8, ptr [[DST_ADD_1]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_3:%.*]] = icmp uge ptr [[DST_ADD_3]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_3]]
|
|
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 3
|
|
; CHECK-NEXT: [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%pre = icmp uge ptr %dst, %lower
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.3 = getelementptr i8, ptr %dst, i64 3
|
|
%dst.add.1 = getelementptr i8, ptr %dst, i64 1
|
|
%cmp.add.1 = icmp uge ptr %dst.add.1, %lower
|
|
%dst.add.2 = getelementptr i8, ptr %dst.add.1, i64 1
|
|
%cmp.add.3 = icmp uge ptr %dst.add.3, %lower
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.3
|
|
%dst.add.4 = getelementptr i8, ptr %dst.add.3, i64 3
|
|
%cmp.add.4 = icmp uge ptr %dst.add.4, %lower
|
|
%res.2 = xor i1 %res.1, %cmp.add.4
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_ult(ptr %dst, ptr %lower, ptr %upper) {
|
|
; CHECK-LABEL: @gep_add_1_ult(
|
|
; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[END]], [[UPPER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1
|
|
; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 2
|
|
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 3
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
|
|
; CHECK-NEXT: [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 4
|
|
; CHECK-NEXT: [[CMP_ADD_5:%.*]] = icmp ult ptr [[DST_ADD_5]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_5]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%end = getelementptr inbounds i8, ptr %dst, i64 4
|
|
%pre = icmp ult ptr %end, %upper
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst, i64 1
|
|
%dst.add.3 = getelementptr inbounds i8, ptr %dst.add.1, i64 2
|
|
%cmp.add.3 = icmp ult ptr %dst.add.3, %upper
|
|
%dst.add.4 = getelementptr inbounds i8, ptr %dst.add.1, i64 3
|
|
%cmp.add.4 = icmp ult ptr %dst.add.4, %upper
|
|
%res.1 = xor i1 %cmp.add.3, %cmp.add.4
|
|
%dst.add.5 = getelementptr inbounds i8, ptr %dst.add.1, i64 4
|
|
%cmp.add.5 = icmp ult ptr %dst.add.5, %upper
|
|
%res.2 = xor i1 %res.1, %cmp.add.5
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {
|
|
; CHECK-LABEL: @gep_add_ult_var_idx(
|
|
; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[IDX:%.*]], 0
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
|
|
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 1
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
|
|
; CHECK-NEXT: [[CMP_ADD_2:%.*]] = icmp ule ptr [[DST_ADD_2]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_ADD_2]]
|
|
; CHECK-NEXT: ret i1 [[RES_1]]
|
|
;
|
|
%not.zero = icmp ne i8 %idx, 0
|
|
call void @llvm.assume(i1 %not.zero)
|
|
%idx.ext = zext i8 %idx to i16
|
|
%dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
|
|
%pre = icmp ult ptr %dst.add.idx, %upper
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 1
|
|
%cmp.add.1 = icmp ule ptr %dst.add.1, %upper
|
|
%dst.add.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 2
|
|
%cmp.add.2 = icmp ule ptr %dst.add.2, %upper
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.2
|
|
ret i1 %res.1
|
|
}
|
|
|
|
define i1 @gep_add_ult_var_idx_sgt_1(ptr %dst, ptr %upper, i8 %idx) {
|
|
; CHECK-LABEL: @gep_add_ult_var_idx_sgt_1(
|
|
; CHECK-NEXT: [[SGT_1:%.*]] = icmp sgt i8 [[IDX:%.*]], 1
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]])
|
|
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 1
|
|
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
|
|
; CHECK-NEXT: [[CMP_ADD_2:%.*]] = icmp ule ptr [[DST_ADD_2]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_ADD_2]]
|
|
; CHECK-NEXT: ret i1 [[RES_1]]
|
|
;
|
|
%sgt.1 = icmp sgt i8 %idx, 1
|
|
call void @llvm.assume(i1 %sgt.1)
|
|
%idx.ext = zext i8 %idx to i16
|
|
%dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
|
|
%pre = icmp ult ptr %dst.add.idx, %upper
|
|
call void @llvm.assume(i1 %pre)
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 1
|
|
%cmp.add.1 = icmp ule ptr %dst.add.1, %upper
|
|
%dst.add.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 2
|
|
%cmp.add.2 = icmp ule ptr %dst.add.2, %upper
|
|
%res.1 = xor i1 %cmp.add.1, %cmp.add.2
|
|
ret i1 %res.1
|
|
}
|
|
|
|
define i1 @gep_add_1_ult_var_idx_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
|
|
; CHECK-LABEL: @gep_add_1_ult_var_idx_inbounds(
|
|
; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
|
|
; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp ult ptr [[DST_ADD_1]], [[UPPER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD_1]])
|
|
; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
|
|
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 1
|
|
; CHECK-NEXT: [[DST_ADD_IDX_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
|
|
; CHECK-NEXT: [[DST_ADD_IDX_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 3
|
|
; CHECK-NEXT: [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%not.zero = icmp ne i8 %len, 0
|
|
call void @llvm.assume(i1 %not.zero)
|
|
%len.ext = zext i8 %len to i16
|
|
%dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 1
|
|
%cmp.add.1 = icmp ult ptr %dst.add.1, %upper
|
|
call void @llvm.assume(i1 %cmp.add.1)
|
|
%cmp.idx.ult.len = icmp ult i8 %idx, %len
|
|
call void @llvm.assume(i1 %cmp.idx.ult.len)
|
|
%idx.ext = zext i8 %idx to i16
|
|
%dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
|
|
%dst.add.idx.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 1
|
|
%cmp.idx.1 = icmp ult ptr %dst.add.idx.1, %upper
|
|
%dst.add.idx.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 2
|
|
%cmp.idx.2 = icmp ult ptr %dst.add.idx.2, %upper
|
|
%res.1 = xor i1 %cmp.idx.1, %cmp.idx.2
|
|
%dst.add.idx.3 = getelementptr inbounds i8, ptr %dst.add.idx, i64 3
|
|
%cmp.idx.3 = icmp ult ptr %dst.add.idx.3, %upper
|
|
%res.2 = xor i1 %res.1, %cmp.idx.3
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_ult_var_idx_only_inner_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
|
|
; CHECK-LABEL: @gep_add_1_ult_var_idx_only_inner_inbounds(
|
|
; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
|
|
; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp ult ptr [[DST_ADD_1]], [[UPPER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD_1]])
|
|
; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
|
|
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_1:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 1
|
|
; CHECK-NEXT: [[CMP_IDX_1:%.*]] = icmp ult ptr [[DST_ADD_IDX_1]], [[UPPER]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_2:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 2
|
|
; CHECK-NEXT: [[CMP_IDX_2:%.*]] = icmp ult ptr [[DST_ADD_IDX_2]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_IDX_1]], [[CMP_IDX_2]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_3:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 3
|
|
; CHECK-NEXT: [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%not.zero = icmp ne i8 %len, 0
|
|
call void @llvm.assume(i1 %not.zero)
|
|
%len.ext = zext i8 %len to i16
|
|
%dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
|
|
%dst.add.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 1
|
|
%cmp.add.1 = icmp ult ptr %dst.add.1, %upper
|
|
call void @llvm.assume(i1 %cmp.add.1)
|
|
%cmp.idx.ult.len = icmp ult i8 %idx, %len
|
|
call void @llvm.assume(i1 %cmp.idx.ult.len)
|
|
%idx.ext = zext i8 %idx to i16
|
|
%dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
|
|
%dst.add.idx.1 = getelementptr i8, ptr %dst.add.idx, i64 1
|
|
%cmp.idx.1 = icmp ult ptr %dst.add.idx.1, %upper
|
|
%dst.add.idx.2 = getelementptr i8, ptr %dst.add.idx, i64 2
|
|
%cmp.idx.2 = icmp ult ptr %dst.add.idx.2, %upper
|
|
%res.1 = xor i1 %cmp.idx.1, %cmp.idx.2
|
|
%dst.add.idx.3 = getelementptr i8, ptr %dst.add.idx, i64 3
|
|
%cmp.idx.3 = icmp ult ptr %dst.add.idx.3, %upper
|
|
%res.2 = xor i1 %res.1, %cmp.idx.3
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @gep_add_1_ult_var_idx_no_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
|
|
; CHECK-LABEL: @gep_add_1_ult_var_idx_no_inbounds(
|
|
; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])
|
|
; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
|
|
; CHECK-NEXT: [[DST_ADD_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 1
|
|
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp ult ptr [[DST_ADD_1]], [[UPPER:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD_1]])
|
|
; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
|
|
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
|
|
; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr i8, ptr [[DST]], i16 [[IDX_EXT]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_1:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 1
|
|
; CHECK-NEXT: [[CMP_IDX_1:%.*]] = icmp ult ptr [[DST_ADD_IDX_1]], [[UPPER]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_2:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 2
|
|
; CHECK-NEXT: [[CMP_IDX_2:%.*]] = icmp ult ptr [[DST_ADD_IDX_2]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_IDX_1]], [[CMP_IDX_2]]
|
|
; CHECK-NEXT: [[DST_ADD_IDX_3:%.*]] = getelementptr i8, ptr [[DST_ADD_IDX]], i64 3
|
|
; CHECK-NEXT: [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
|
|
; CHECK-NEXT: ret i1 [[RES_2]]
|
|
;
|
|
%not.zero = icmp ne i8 %len, 0
|
|
call void @llvm.assume(i1 %not.zero)
|
|
%len.ext = zext i8 %len to i16
|
|
%dst.add.len = getelementptr i8, ptr %dst, i16 %len.ext
|
|
%dst.add.1 = getelementptr i8, ptr %dst.add.len, i64 1
|
|
%cmp.add.1 = icmp ult ptr %dst.add.1, %upper
|
|
call void @llvm.assume(i1 %cmp.add.1)
|
|
%cmp.idx.ult.len = icmp ult i8 %idx, %len
|
|
call void @llvm.assume(i1 %cmp.idx.ult.len)
|
|
%idx.ext = zext i8 %idx to i16
|
|
%dst.add.idx = getelementptr i8, ptr %dst, i16 %idx.ext
|
|
%dst.add.idx.1 = getelementptr i8, ptr %dst.add.idx, i64 1
|
|
%cmp.idx.1 = icmp ult ptr %dst.add.idx.1, %upper
|
|
%dst.add.idx.2 = getelementptr i8, ptr %dst.add.idx, i64 2
|
|
%cmp.idx.2 = icmp ult ptr %dst.add.idx.2, %upper
|
|
%res.1 = xor i1 %cmp.idx.1, %cmp.idx.2
|
|
%dst.add.idx.3 = getelementptr i8, ptr %dst.add.idx, i64 3
|
|
%cmp.idx.3 = icmp ult ptr %dst.add.idx.3, %upper
|
|
%res.2 = xor i1 %res.1, %cmp.idx.3
|
|
ret i1 %res.2
|
|
}
|
|
|
|
define i1 @test_chained_no_inbounds(ptr %A, ptr %B) {
|
|
; CHECK-LABEL: @test_chained_no_inbounds(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[B_1:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 1
|
|
; CHECK-NEXT: [[B_2:%.*]] = getelementptr i8, ptr [[B_1]], i64 1
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt ptr [[A:%.*]], null
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[B_1]], [[B_2]]
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
|
; CHECK: then:
|
|
; CHECK-NEXT: ret i1 true
|
|
; CHECK: else:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
entry:
|
|
%B.1 = getelementptr i8, ptr %B, i64 1
|
|
%B.2 = getelementptr i8, ptr %B.1, i64 1
|
|
%c.1 = icmp ugt ptr %A, null
|
|
%c.2 = icmp ugt ptr %B.1, %B.2
|
|
%or = or i1 %c.1, %c.2
|
|
br i1 %or, label %then, label %else
|
|
|
|
then:
|
|
ret i1 true
|
|
|
|
else:
|
|
ret i1 false
|
|
}
|