llvm-6502/test/CodeGen/Thumb/PR17309.ll
David Peixotto 7014d274e4 17309 ARM backend incorrectly lowers COPY_STRUCT_BYVAL_I32 for thumb1 targets
This commit implements the correct lowering of the
COPY_STRUCT_BYVAL_I32 pseudo-instruction for thumb1 targets.
Previously, the lowering of COPY_STRUCT_BYVAL_I32 generated the
post-increment forms of ldr/ldrh/ldrb instructions. Thumb1 does not
have the post-increment form of these instructions so the generated
assembly contained invalid instructions.

Passing the generated assembly to gcc caused it to complain with an
error like this:

  Error: cannot honor width suffix -- `ldrb r3,[r0],#1'

and the integrated assembler would generate an object file with an
invalid instruction encoding.

This commit contains a small test case that demonstrates the problem
with thumb1 targets as well as an expanded test case that more
throughly tests the lowering of byval struct passing for arm,
thumb1, and thumb2 targets.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192916 91177308-0d34-0410-b5e6-96231b3b80d8
2013-10-17 19:52:05 +00:00

58 lines
2.1 KiB
LLVM

; RUN: llc -mtriple thumbv5-none-linux-gnueabi < %s | FileCheck %s
%struct.C = type { [1000 x i8] }
%struct.S = type { [1000 x i16] }
%struct.I = type { [1000 x i32] }
;CHECK-LABEL: pass_C:
;CHECK-NOT: ldrb r{{[0-9]+}}, [{{.*}}], #1
;CHECK-NOT: strb r{{[0-9]+}}, [{{.*}}], #1
define void @pass_C() #0 {
entry:
%c = alloca %struct.C, align 1
%0 = getelementptr inbounds %struct.C* %c, i32 0, i32 0, i32 0
call void @llvm.lifetime.start(i64 1000, i8* %0) #1
call void @use_C(%struct.C* byval %c) #3
call void @llvm.lifetime.end(i64 1000, i8* %0) #1
ret void
}
;CHECK-LABEL: pass_S:
;CHECK-NOT: ldrh r{{[0-9]+}}, [{{.*}}], #2
;CHECK-NOT: strh r{{[0-9]+}}, [{{.*}}], #2
define void @pass_S() #0 {
entry:
%s = alloca %struct.S, align 2
%0 = bitcast %struct.S* %s to i8*
call void @llvm.lifetime.start(i64 2000, i8* %0) #1
call void @use_S(%struct.S* byval %s) #3
call void @llvm.lifetime.end(i64 2000, i8* %0) #1
ret void
}
;CHECK-LABEL: pass_I:
;CHECK-NOT: ldr r{{[0-9]+}}, [{{.*}}], #4
;CHECK-NOT: str r{{[0-9]+}}, [{{.*}}], #4
define void @pass_I() #0 {
entry:
%i = alloca %struct.I, align 4
%0 = bitcast %struct.I* %i to i8*
call void @llvm.lifetime.start(i64 4000, i8* %0) #1
call void @use_I(%struct.I* byval %i) #3
call void @llvm.lifetime.end(i64 4000, i8* %0) #1
ret void
}
declare void @use_C(%struct.C* byval) #2
declare void @use_S(%struct.S* byval) #2
declare void @use_I(%struct.I* byval) #2
declare void @llvm.lifetime.start(i64, i8* nocapture) #1
declare void @llvm.lifetime.end(i64, i8* nocapture) #1
attributes #0 = { nounwind optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
attributes #2 = { optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind optsize }