llvm/test/CodeGen/PowerPC/ppc64le-aggregates.ll
Ehsan Amiri 38caf19333 Adding -verify-machineinstrs option to PowerPC tests
Currently we have a number of tests that fail with -verify-machineinstrs.
To detect this cases earlier we add the option to the testcases with the
exception of tests that will currently fail with this option. PR 27456 keeps
track of this failures.

No code review, as discussed with Hal Finkel.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277624 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-03 18:17:35 +00:00

337 lines
8.8 KiB
LLVM

; RUN: llc -verify-machineinstrs < %s -march=ppc64le -mcpu=pwr8 -mattr=+altivec -mattr=-vsx | FileCheck %s
; RUN: llc -verify-machineinstrs < %s -march=ppc64le -mattr=+altivec -mattr=-vsx | FileCheck %s
; Currently VSX support is disabled for this test because we generate lxsdx
; instead of lfd, and stxsdx instead of stfd. That is a poor choice when we
; have reg+imm addressing, and is on the list of things to be fixed.
; The second run step is to ensure that -march=ppc64le is adequate to select
; the same feature set as with -mcpu=pwr8 since that is the baseline for ppc64le.
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"
;
; Verify use of registers for float/vector aggregate return.
;
define [8 x float] @return_float([8 x float] %x) {
entry:
ret [8 x float] %x
}
; CHECK-LABEL: @return_float
; CHECK: %entry
; CHECK-NEXT: blr
define [8 x double] @return_double([8 x double] %x) {
entry:
ret [8 x double] %x
}
; CHECK-LABEL: @return_double
; CHECK: %entry
; CHECK-NEXT: blr
define [4 x ppc_fp128] @return_ppcf128([4 x ppc_fp128] %x) {
entry:
ret [4 x ppc_fp128] %x
}
; CHECK-LABEL: @return_ppcf128
; CHECK: %entry
; CHECK-NEXT: blr
define [8 x <4 x i32>] @return_v4i32([8 x <4 x i32>] %x) {
entry:
ret [8 x <4 x i32>] %x
}
; CHECK-LABEL: @return_v4i32
; CHECK: %entry
; CHECK-NEXT: blr
;
; Verify amount of space taken up by aggregates in the parameter save area.
;
define i64 @callee_float([7 x float] %a, [7 x float] %b, i64 %c) {
entry:
ret i64 %c
}
; CHECK-LABEL: @callee_float
; CHECK: ld 3, 96(1)
; CHECK: blr
define void @caller_float(i64 %x, [7 x float] %y) {
entry:
tail call void @test_float([7 x float] %y, [7 x float] %y, i64 %x)
ret void
}
; CHECK-LABEL: @caller_float
; CHECK: std 3, 96(1)
; CHECK: bl test_float
declare void @test_float([7 x float], [7 x float], i64)
define i64 @callee_double(i64 %a, [7 x double] %b, i64 %c) {
entry:
ret i64 %c
}
; CHECK-LABEL: @callee_double
; CHECK: ld 3, 96(1)
; CHECK: blr
define void @caller_double(i64 %x, [7 x double] %y) {
entry:
tail call void @test_double(i64 %x, [7 x double] %y, i64 %x)
ret void
}
; CHECK-LABEL: @caller_double
; CHECK: std 3, 96(1)
; CHECK: bl test_double
declare void @test_double(i64, [7 x double], i64)
define i64 @callee_ppcf128(i64 %a, [4 x ppc_fp128] %b, i64 %c) {
entry:
ret i64 %c
}
; CHECK-LABEL: @callee_ppcf128
; CHECK: ld 3, 104(1)
; CHECK: blr
define void @caller_ppcf128(i64 %x, [4 x ppc_fp128] %y) {
entry:
tail call void @test_ppcf128(i64 %x, [4 x ppc_fp128] %y, i64 %x)
ret void
}
; CHECK-LABEL: @caller_ppcf128
; CHECK: std 3, 104(1)
; CHECK: bl test_ppcf128
declare void @test_ppcf128(i64, [4 x ppc_fp128], i64)
define i64 @callee_i64(i64 %a, [7 x i64] %b, i64 %c) {
entry:
ret i64 %c
}
; CHECK-LABEL: @callee_i64
; CHECK: ld 3, 96(1)
; CHECK: blr
define void @caller_i64(i64 %x, [7 x i64] %y) {
entry:
tail call void @test_i64(i64 %x, [7 x i64] %y, i64 %x)
ret void
}
; CHECK-LABEL: @caller_i64
; CHECK: std 3, 96(1)
; CHECK: bl test_i64
declare void @test_i64(i64, [7 x i64], i64)
define i64 @callee_i128(i64 %a, [4 x i128] %b, i64 %c) {
entry:
ret i64 %c
}
; CHECK-LABEL: @callee_i128
; CHECK: ld 3, 112(1)
; CHECK: blr
define void @caller_i128(i64 %x, [4 x i128] %y) {
entry:
tail call void @test_i128(i64 %x, [4 x i128] %y, i64 %x)
ret void
}
; CHECK-LABEL: @caller_i128
; CHECK: std 3, 112(1)
; CHECK: bl test_i128
declare void @test_i128(i64, [4 x i128], i64)
define i64 @callee_v4i32(i64 %a, [4 x <4 x i32>] %b, i64 %c) {
entry:
ret i64 %c
}
; CHECK-LABEL: @callee_v4i32
; CHECK: ld 3, 112(1)
; CHECK: blr
define void @caller_v4i32(i64 %x, [4 x <4 x i32>] %y) {
entry:
tail call void @test_v4i32(i64 %x, [4 x <4 x i32>] %y, i64 %x)
ret void
}
; CHECK-LABEL: @caller_v4i32
; CHECK: std 3, 112(1)
; CHECK: bl test_v4i32
declare void @test_v4i32(i64, [4 x <4 x i32>], i64)
;
; Verify handling of floating point arguments in GPRs
;
%struct.float8 = type { [8 x float] }
%struct.float5 = type { [5 x float] }
%struct.float2 = type { [2 x float] }
@g8 = common global %struct.float8 zeroinitializer, align 4
@g5 = common global %struct.float5 zeroinitializer, align 4
@g2 = common global %struct.float2 zeroinitializer, align 4
define float @callee0([7 x float] %a, [7 x float] %b) {
entry:
%b.extract = extractvalue [7 x float] %b, 6
ret float %b.extract
}
; CHECK-LABEL: @callee0
; CHECK: stw 10, [[OFF:.*]](1)
; CHECK: lfs 1, [[OFF]](1)
; CHECK: blr
define void @caller0([7 x float] %a) {
entry:
tail call void @test0([7 x float] %a, [7 x float] %a)
ret void
}
; CHECK-LABEL: @caller0
; CHECK-DAG: fmr 8, 1
; CHECK-DAG: fmr 9, 2
; CHECK-DAG: fmr 10, 3
; CHECK-DAG: fmr 11, 4
; CHECK-DAG: fmr 12, 5
; CHECK-DAG: fmr 13, 6
; CHECK-DAG: stfs 7, [[OFF:[0-9]+]](1)
; CHECK-DAG: lwz 10, [[OFF]](1)
; CHECK: bl test0
declare void @test0([7 x float], [7 x float])
define float @callee1([8 x float] %a, [8 x float] %b) {
entry:
%b.extract = extractvalue [8 x float] %b, 7
ret float %b.extract
}
; CHECK-LABEL: @callee1
; CHECK: rldicl [[REG:[0-9]+]], 10, 32, 32
; CHECK: stw [[REG]], [[OFF:.*]](1)
; CHECK: lfs 1, [[OFF]](1)
; CHECK: blr
define void @caller1([8 x float] %a) {
entry:
tail call void @test1([8 x float] %a, [8 x float] %a)
ret void
}
; CHECK-LABEL: @caller1
; CHECK-DAG: fmr 9, 1
; CHECK-DAG: fmr 10, 2
; CHECK-DAG: fmr 11, 3
; CHECK-DAG: fmr 12, 4
; CHECK-DAG: fmr 13, 5
; CHECK-DAG: stfs 5, [[OFF0:[0-9]+]](1)
; CHECK-DAG: stfs 6, [[OFF1:[0-9]+]](1)
; CHECK-DAG: stfs 7, [[OFF2:[0-9]+]](1)
; CHECK-DAG: stfs 8, [[OFF3:[0-9]+]](1)
; CHECK-DAG: lwz [[REG0:[0-9]+]], [[OFF0]](1)
; CHECK-DAG: lwz [[REG1:[0-9]+]], [[OFF1]](1)
; CHECK-DAG: lwz [[REG2:[0-9]+]], [[OFF2]](1)
; CHECK-DAG: lwz [[REG3:[0-9]+]], [[OFF3]](1)
; CHECK-DAG: sldi [[REG1]], [[REG1]], 32
; CHECK-DAG: sldi [[REG3]], [[REG3]], 32
; CHECK-DAG: or 9, [[REG0]], [[REG1]]
; CHECK-DAG: or 10, [[REG2]], [[REG3]]
; CHECK: bl test1
declare void @test1([8 x float], [8 x float])
define float @callee2([8 x float] %a, [5 x float] %b, [2 x float] %c) {
entry:
%c.extract = extractvalue [2 x float] %c, 1
ret float %c.extract
}
; CHECK-LABEL: @callee2
; CHECK: rldicl [[REG:[0-9]+]], 10, 32, 32
; CHECK: stw [[REG]], [[OFF:.*]](1)
; CHECK: lfs 1, [[OFF]](1)
; CHECK: blr
define void @caller2() {
entry:
%0 = load [8 x float], [8 x float]* getelementptr inbounds (%struct.float8, %struct.float8* @g8, i64 0, i32 0), align 4
%1 = load [5 x float], [5 x float]* getelementptr inbounds (%struct.float5, %struct.float5* @g5, i64 0, i32 0), align 4
%2 = load [2 x float], [2 x float]* getelementptr inbounds (%struct.float2, %struct.float2* @g2, i64 0, i32 0), align 4
tail call void @test2([8 x float] %0, [5 x float] %1, [2 x float] %2)
ret void
}
; CHECK-LABEL: @caller2
; CHECK: ld {{[0-9]+}}, .LC
; CHECK-DAG: lfs 1, 0({{[0-9]+}})
; CHECK-DAG: lfs 2, 4({{[0-9]+}})
; CHECK-DAG: lfs 3, 8({{[0-9]+}})
; CHECK-DAG: lfs 4, 12({{[0-9]+}})
; CHECK-DAG: lfs 5, 16({{[0-9]+}})
; CHECK-DAG: lfs 6, 20({{[0-9]+}})
; CHECK-DAG: lfs 7, 24({{[0-9]+}})
; CHECK-DAG: lfs 8, 28({{[0-9]+}})
; CHECK-DAG: lfs 9, 0({{[0-9]+}})
; CHECK-DAG: lfs 10, 4({{[0-9]+}})
; CHECK-DAG: lfs 11, 8({{[0-9]+}})
; CHECK-DAG: lfs 12, 12({{[0-9]+}})
; CHECK-DAG: lfs 13, 16({{[0-9]+}})
; CHECK-DAG: lwz [[REG0:[0-9]+]], 0({{[0-9]+}})
; CHECK-DAG: lwz [[REG1:[0-9]+]], 4({{[0-9]+}})
; CHECK-DAG: sldi [[REG2:[0-9]+]], [[REG1]], 32
; CHECK-DAG: or 10, [[REG0]], [[REG2]]
; CHECK: bl test2
declare void @test2([8 x float], [5 x float], [2 x float])
define double @callee3([8 x float] %a, [5 x float] %b, double %c) {
entry:
ret double %c
}
; CHECK-LABEL: @callee3
; CHECK: std 10, [[OFF:.*]](1)
; CHECK: lfd 1, [[OFF]](1)
; CHECK: blr
define void @caller3(double %d) {
entry:
%0 = load [8 x float], [8 x float]* getelementptr inbounds (%struct.float8, %struct.float8* @g8, i64 0, i32 0), align 4
%1 = load [5 x float], [5 x float]* getelementptr inbounds (%struct.float5, %struct.float5* @g5, i64 0, i32 0), align 4
tail call void @test3([8 x float] %0, [5 x float] %1, double %d)
ret void
}
; CHECK-LABEL: @caller3
; CHECK: stfd 1, [[OFF:.*]](1)
; CHECK: ld 10, [[OFF]](1)
; CHECK: bl test3
declare void @test3([8 x float], [5 x float], double)
define float @callee4([8 x float] %a, [5 x float] %b, float %c) {
entry:
ret float %c
}
; CHECK-LABEL: @callee4
; CHECK: stw 10, [[OFF:.*]](1)
; CHECK: lfs 1, [[OFF]](1)
; CHECK: blr
define void @caller4(float %f) {
entry:
%0 = load [8 x float], [8 x float]* getelementptr inbounds (%struct.float8, %struct.float8* @g8, i64 0, i32 0), align 4
%1 = load [5 x float], [5 x float]* getelementptr inbounds (%struct.float5, %struct.float5* @g5, i64 0, i32 0), align 4
tail call void @test4([8 x float] %0, [5 x float] %1, float %f)
ret void
}
; CHECK-LABEL: @caller4
; CHECK: stfs 1, [[OFF:.*]](1)
; CHECK: lwz 10, [[OFF]](1)
; CHECK: bl test4
declare void @test4([8 x float], [5 x float], float)