Add tests exercising the future enancement of folding library function calls with arguments involving subobjects such as elements of arrays or struct members.
132 lines
5.8 KiB
LLVM
132 lines
5.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; Verify that strlen calls with elements of constant arrays are folded.
|
|
;
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
declare i32 @strcmp(i8*, i8*)
|
|
|
|
@a5 = constant [5 x [4 x i8]] [[4 x i8] c"123\00", [4 x i8] c"123\00", [4 x i8] c"12\00\00", [4 x i8] zeroinitializer, [4 x i8] zeroinitializer]
|
|
|
|
|
|
; Fold strcmp(a5[0], a5[1]) to '1' - '1'.
|
|
|
|
define i32 @fold_strcmp_a5i0_a5i1_to_0() {
|
|
; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_to_0(
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0))
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Do not fold strcmp(a5[0], a5[I]) where the index I is not constant.
|
|
|
|
define i32 @call_strcmp_a5i0_a5iI(i64 %I) {
|
|
; CHECK-LABEL: @call_strcmp_a5i0_a5iI(
|
|
; CHECK-NEXT: [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[Q]])
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Same as above but for strcmp(a5[I], a5[0]).
|
|
|
|
define i32 @call_strcmp_a5iI_a5i0(i64 %I) {
|
|
; CHECK-LABEL: @call_strcmp_a5iI_a5i0(
|
|
; CHECK-NEXT: [[P:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) [[P]], i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0))
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Fold strcmp(a5[0], &a5[1][1]) to '1' - '2'.
|
|
|
|
define i32 @fold_strcmp_a5i0_a5i1_p1_to_0() {
|
|
; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_p1_to_0(
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1))
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Do not fold strcmp(a5[0], &a5[1][I]) when the index I is not constant.
|
|
|
|
define i32 @call_strcmp_a5i0_a5i1_pI(i64 %I) {
|
|
; CHECK-LABEL: @call_strcmp_a5i0_a5i1_pI(
|
|
; CHECK-NEXT: [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 [[I:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[Q]])
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 %I
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Fold strcmp(&a5[0][1], a5[1]) to '2' - '1'.
|
|
|
|
define i32 @fold_strcmp_a5i0_p1_a5i1_to_0() {
|
|
; CHECK-LABEL: @fold_strcmp_a5i0_p1_a5i1_to_0(
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0))
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Fold strcmp(a5[0], a5[2]) to a5[0][2] - a5[2][2] or 1.
|
|
|
|
define i32 @fold_strcmp_a5i0_a5i2_to_0() {
|
|
; CHECK-LABEL: @fold_strcmp_a5i0_a5i2_to_0(
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0))
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0
|
|
|
|
%cmp = call i32 @strcmp(i8* %p, i8* %q)
|
|
ret i32 %cmp
|
|
}
|
|
|
|
|
|
; Fold strcmp(a5[2], a5[0]) to a5[0][2] - a5[2][2] or 1.
|
|
|
|
define i32 @fold_strcmp_a5i2_a5i0_to_m1() {
|
|
; CHECK-LABEL: @fold_strcmp_a5i2_a5i0_to_m1(
|
|
; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0))
|
|
; CHECK-NEXT: ret i32 [[CMP]]
|
|
;
|
|
%p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
|
|
%q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0
|
|
|
|
%cmp = call i32 @strcmp(i8* %q, i8* %p)
|
|
ret i32 %cmp
|
|
}
|