Files
clang-p2996/llvm/test/Transforms/AggressiveInstCombine/patterned-load.ll
2023-03-23 23:31:22 +09:00

183 lines
7.0 KiB
LLVM
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=aggressive-instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=CHECK,LE
; RUN: opt < %s -passes=aggressive-instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=CHECK,BE
@constarray1 = internal constant [8 x i8] c"\01\00\01\00\01\00\01\00", align 4
@constarray2 = internal constant [8 x i8] c"\FF\FF\01\00\01\00\01\00", align 4
@g = internal constant i32 42
@constptrarray = internal constant [4 x ptr] [ptr @g, ptr @g, ptr @g, ptr @g], align 4
@constpackedstruct = internal constant <{[8 x i8]}> <{[8 x i8] c"\01\00\01\00\01\00\01\00"}>, align 4
@conststruct = internal constant {i16, [8 x i8]} {i16 1, [8 x i8] c"\01\00\01\00\01\00\01\00"}, align 4
define i8 @inbounds_gep_load_i8_align2(i64 %idx){
; CHECK-LABEL: @inbounds_gep_load_i8_align2(
; CHECK-NEXT: ret i8 1
;
%1 = getelementptr inbounds i8, ptr @constarray1, i64 %idx
%2 = load i8, ptr %1, align 2
ret i8 %2
}
; can't be folded because access with i8 strides is not patterned.
define i8 @inbounds_gep_load_i8_align1(i64 %idx){
; CHECK-LABEL: @inbounds_gep_load_i8_align1(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr @constarray1, i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
; CHECK-NEXT: ret i8 [[TMP2]]
;
%1 = getelementptr inbounds i8, ptr @constarray1, i64 %idx
%2 = load i8, ptr %1, align 1
ret i8 %2
}
; can't be folded because volatile load cannot assure same results.
define i8 @inbounds_gep_load_i8_align2_volatile(i64 %idx){
; CHECK-LABEL: @inbounds_gep_load_i8_align2_volatile(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr @constarray1, i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = load volatile i8, ptr [[TMP1]], align 2
; CHECK-NEXT: ret i8 [[TMP2]]
;
%1 = getelementptr inbounds i8, ptr @constarray1, i64 %idx
%2 = load volatile i8, ptr %1, align 2
ret i8 %2
}
declare ptr @llvm.ptrmask.p0.i64(ptr , i64)
; can't be folded because ptrmask can change ptr, while preserving provenance
define i8 @inbounds_gep_load_i8_align2_ptrmasked(i64 %idx, i64 %mask){
; CHECK-LABEL: @inbounds_gep_load_i8_align2_ptrmasked(
; CHECK-NEXT: ret i8 1
;
%1 = call ptr @llvm.ptrmask.p0.i64(ptr @constarray1, i64 %mask)
%2 = getelementptr inbounds i8, ptr %1, i64 %idx
%3 = load i8, ptr %2, align 2
ret i8 %3
}
; TODO: this will be ret i32 65537(LE), 16777472(BE)
define i32 @inbounds_gep_i16_load_i32_align1(i64 %idx){
; CHECK-LABEL: @inbounds_gep_i16_load_i32_align1(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr @constarray1, i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 1
; CHECK-NEXT: ret i32 [[TMP2]]
;
%1 = getelementptr inbounds i16, ptr @constarray1, i64 %idx
%2 = load i32, ptr %1, align 1
ret i32 %2
}
; TODO: this will be ret i32 65537(LE), 16777472(BE)
define i32 @inbounds_gep_i32_load_i32_align8(i64 %idx){
; CHECK-LABEL: @inbounds_gep_i32_load_i32_align8(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr @constarray1, i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 8
; CHECK-NEXT: ret i32 [[TMP2]]
;
%1 = getelementptr inbounds i32, ptr @constarray1, i64 %idx
%2 = load i32, ptr %1, align 8
ret i32 %2
}
; TODO: this will be ret i32 65547(LE), 16777472(BE)
define i32 @inbounds_gep_i32_load_i32_const_offset(i64 %idx){
; CHECK-LABEL: @inbounds_gep_i32_load_i32_const_offset(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr @constarray2, i64 1
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: ret i32 [[TMP3]]
;
%1 = getelementptr inbounds i16, ptr @constarray2, i64 1
%2 = getelementptr inbounds i32, ptr %1, i64 %idx
%3 = load i32, ptr %2, align 4
ret i32 %3
}
define i32 @gep_load_i32_align2_const_offset(i64 %idx){
; LE-LABEL: @gep_load_i32_align2_const_offset(
; LE-NEXT: ret i32 65537
;
; BE-LABEL: @gep_load_i32_align2_const_offset(
; BE-NEXT: ret i32 16777472
;
%1 = getelementptr i16, ptr @constarray1, i64 -2
%2 = getelementptr [3 x i16], ptr %1, i64 %idx
%3 = load i32, ptr %2, align 2
ret i32 %3
}
; can't be folded because if gep is non-inbounds,
; the offsets are silently-wrapped with twos complement arithmetic(mod 2**64).
; So the load operand can be a base pointer of constarray2.
define i32 @gep_load_i32_align2_const_offset_wrap(i64 %idx){
; CHECK-LABEL: @gep_load_i32_align2_const_offset_wrap(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i16, ptr @constarray2, i64 -2
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [3 x i16], ptr [[TMP1]], i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 2
; CHECK-NEXT: ret i32 [[TMP3]]
;
%1 = getelementptr i16, ptr @constarray2, i64 -2
%2 = getelementptr [3 x i16], ptr %1, i64 %idx
%3 = load i32, ptr %2, align 2
ret i32 %3
}
; TODO: this will be ret i32 42
define i32 @inbounds_gep_i32_load_i32_const_ptr_array(i64 %idx){
; CHECK-LABEL: @inbounds_gep_i32_load_i32_const_ptr_array(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds ptr, ptr @constptrarray, i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: ret i32 [[TMP3]]
;
%1 = getelementptr inbounds ptr, ptr @constptrarray, i64 %idx
%2 = load ptr, ptr %1, align 4
%3 = load i32, ptr %2, align 4
ret i32 %3
}
define i32 @inbounds_gep_i32_load_i32_align4_packedstruct(i64 %idx){
; LE-LABEL: @inbounds_gep_i32_load_i32_align4_packedstruct(
; LE-NEXT: ret i32 65537
;
; BE-LABEL: @inbounds_gep_i32_load_i32_align4_packedstruct(
; BE-NEXT: ret i32 16777472
;
%1 = getelementptr inbounds i32, ptr @constpackedstruct, i64 %idx
%2 = load i32, ptr %1, align 4
ret i32 %2
}
; can't be folded because results are not equal
define i32 @inbounds_gep_i8_load_i32_align1_packedstruct(i64 %idx){
; CHECK-LABEL: @inbounds_gep_i8_load_i32_align1_packedstruct(
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr @constpackedstruct, i64 [[IDX:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 1
; CHECK-NEXT: ret i32 [[TMP2]]
;
%1 = getelementptr inbounds i8, ptr @constpackedstruct, i64 %idx
%2 = load i32, ptr %1, align 1
ret i32 %2
}
; TODO: this coould be folded into 65537(LE), 16777472(BE)
define i32 @inbounds_gep_i32_load_i32_align4_struct_with_const_offset(i64 %idx){
; LE-LABEL: @inbounds_gep_i32_load_i32_align4_struct_with_const_offset(
; LE-NEXT: ret i32 65537
;
; BE-LABEL: @inbounds_gep_i32_load_i32_align4_struct_with_const_offset(
; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr @conststruct, i64 1
; BE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[IDX:%.*]]
; BE-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
; BE-NEXT: ret i32 [[TMP3]]
;
%1 = getelementptr inbounds i16, ptr @conststruct, i64 1
%2 = getelementptr inbounds i32, ptr %1, i64 %idx
%3 = load i32, ptr %2, align 4
ret i32 %3
}