
Move GEP offset collection to separate helper function and collect variable and constant offsets in OffsetResult. For now, this only supports 1 VariableOffset, but the new code structure can be more easily extended to handle more offsets in the future. The refactoring drops the check that the VariableOffset >= -1 * constant offset. This is not needed to check whether the constraint is monotonically increasing. The constant factors can be ignored, the constraint will be monotonically increasing if all variables are positive. See https://alive2.llvm.org/ce/z/ah2uSQ, https://alive2.llvm.org/ce/z/NCADNZ
325 lines
15 KiB
LLVM
325 lines
15 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_1(ptr %dst) {
|
|
; CHECK-LABEL: @test_outer_gep_last_index_no_overflow_all_inbounds_1(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
|
|
%upper = getelementptr inbounds ptr, ptr %dst, i64 2
|
|
%gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_2(ptr %dst) {
|
|
; CHECK-LABEL: @test_outer_gep_last_index_no_overflow_all_inbounds_2(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
|
|
%upper = getelementptr inbounds ptr, ptr %dst, i64 3
|
|
%gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_outer_gep_last_index_overflow_all_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_outer_gep_last_index_overflow_all_inbounds(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 2
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
|
|
%upper = getelementptr inbounds ptr, ptr %dst, i64 2
|
|
%gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 2
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_ult_true_all_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_all_inbounds(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_all_inbounds(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c = icmp uge ptr %gep.1, %dst.0
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_ult_false_all_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_false_all_inbounds(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 2
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds_2(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_all_inbounds_2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 2
|
|
%c = icmp uge ptr %gep.1, %dst.0
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_all_inbounds_overflow(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_all_inbounds_overflow(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 6
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 6
|
|
%gep.1 = getelementptr i32, ptr %dst.0, i64 2
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr i32, ptr %dst.0, i64 1
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_uge_true_inc_gep_not_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_inc_gep_not_inbounds(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr i32, ptr %dst.0, i64 1
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_ult_false_inc_gep_not_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_false_inc_gep_not_inbounds(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
|
|
%gep.1 = getelementptr i32, ptr %dst.0, i64 2
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds_overflow(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds_overflow(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 5
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
entry:
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 5
|
|
%gep.1 = getelementptr i32, ptr %dst.0, i64 2
|
|
%c = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
|
|
%upper = getelementptr inbounds ptr, ptr %dst, i64 2
|
|
%gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_outer_gep_last_index_no_overflow_all_inbounds(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_outer_gep_last_index_no_overflow_all_inbounds(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
|
|
%upper = getelementptr inbounds ptr, ptr %dst, i64 2
|
|
%gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_1(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_1(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 1
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 1
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 2
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_2(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_2(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 2
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_3(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_3(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 3
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 3
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_4(ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_4(
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 4
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 4
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_5(i64 %off, ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_5(
|
|
; CHECK-NEXT: [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%off.ult = icmp ule i64 %off, 2
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 5
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ule ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_6(i64 %off, ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_6(
|
|
; CHECK-NEXT: [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%off.ult = icmp ule i64 %off, 2
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 5
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|
|
|
|
define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_7(i64 %off, ptr %dst) {
|
|
; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_7(
|
|
; CHECK-NEXT: [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2
|
|
; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0
|
|
; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[OFF]]
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
|
|
; CHECK-NEXT: ret i1 [[C_1]]
|
|
;
|
|
%off.ult = icmp ule i64 %off, 2
|
|
%dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
|
|
%upper = getelementptr inbounds i32, ptr %dst, i64 %off
|
|
%gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
|
|
%c.1 = icmp ult ptr %gep.1, %upper
|
|
ret i1 %c.1
|
|
}
|