This is a recommit of #107120 . The original PR was approved but failed buildbot. The newly added tests should only be run for compilers that support the ARM target. This has been resolved by adding a config file for these tests. - Pass optimizes memcpy's by padding out destinations and sources to a full word to make ARM backend generate full word loads instead of loading a single byte (ldrb) and/or half word (ldrh). Only pads destination when it's a stack allocated constant size array and source when it's constant string. Heuristic to decide whether to pad or not is very basic and could be improved to allow more examples to be padded. - Pass works at the midend level
46 lines
1.9 KiB
LLVM
46 lines
1.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -mtriple=arm-none-eabi -passes=globalopt -S | FileCheck %s
|
|
%struct.P = type { i32, [13 x i8] }
|
|
|
|
; CHECK-NOT: [16 x i8]
|
|
@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
|
|
|
|
; Function Attrs: nounwind
|
|
define i32 @main() {
|
|
; CHECK-LABEL: define i32 @main() local_unnamed_addr {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[P:%.*]] = alloca [[STRUCT_P:%.*]], align 4
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 20, ptr nonnull [[P]])
|
|
; CHECK-NEXT: store i32 10, ptr [[P]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
|
; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [[STRUCT_P]], ptr [[P]], i32 0, i32 1, i32 0
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[ARRAYDECAY]], ptr align 1 @.str, i32 13, i1 false)
|
|
; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(ptr [[ARRAYDECAY]])
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 20, ptr nonnull [[P]])
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
%p = alloca %struct.P, align 4
|
|
call void @llvm.lifetime.start(i64 20, ptr nonnull %p) #2
|
|
store i32 10, ptr %p, align 4, !tbaa !1
|
|
%arraydecay = getelementptr inbounds %struct.P, ptr %p, i32 0, i32 1, i32 0
|
|
call void @llvm.memcpy.p0i8.p0i8.i32(ptr align 1 %arraydecay, ptr align 1 @.str, i32 13, i1 false)
|
|
%puts = call i32 @puts(ptr %arraydecay)
|
|
call void @llvm.lifetime.end(i64 20, ptr nonnull %p) #2
|
|
ret i32 0
|
|
}
|
|
|
|
declare i32 @puts(ptr nocapture readonly) #2
|
|
|
|
!1 = !{!2, !3, i64 0}
|
|
!2 = !{!"P", !3, i64 0, !4, i64 4}
|
|
!3 = !{!"int", !4, i64 0}
|
|
!4 = !{!"omnipotent char", !5, i64 0}
|
|
!5 = !{!"Simple C/C++ TBAA"}
|
|
;.
|
|
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]], i64 0}
|
|
; CHECK: [[META1]] = !{!"P", [[META2]], i64 0, [[META3:![0-9]+]], i64 4}
|
|
; CHECK: [[META2]] = !{!"int", [[META3]], i64 0}
|
|
; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
|
|
; CHECK: [[META4]] = !{!"Simple C/C++ TBAA"}
|
|
;.
|