llvm/test/CodeGen/PowerPC/ppc64le-aggregates.ll
David Blaikie 5a70dd1d82 [opaque pointer type] Add textual IR support for explicit type parameter to gep operator
Similar to gep (r230786) and load (r230794) changes.

Similar migration script can be used to update test cases, which
successfully migrated all of LLVM and Polly, but about 4 test cases
needed manually changes in Clang.

(this script will read the contents of stdin and massage it into stdout
- wrap it in the 'apply.sh' script shown in previous commits + xargs to
apply it over a large set of test cases)

import fileinput
import sys
import re

rep = re.compile(r"(getelementptr(?:\s+inbounds)?\s*\()((<\d*\s+x\s+)?([^@]*?)(|\s*addrspace\(\d+\))\s*\*(?(3)>)\s*)(?=$|%|@|null|undef|blockaddress|getelementptr|addrspacecast|bitcast|inttoptr|zeroinitializer|<|\[\[[a-zA-Z]|\{\{)", re.MULTILINE | re.DOTALL)

def conv(match):
  line = match.group(1)
  line += match.group(4)
  line += ", "
  line += match.group(2)
  return line

line = sys.stdin.read()
off = 0
for match in re.finditer(rep, line):
  sys.stdout.write(line[off:match.start()])
  sys.stdout.write(conv(match))
  off = match.end()
sys.stdout.write(line[off:])

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232184 91177308-0d34-0410-b5e6-96231b3b80d8
2015-03-13 18:20:45 +00:00

337 lines
8.7 KiB
LLVM

; RUN: llc < %s -march=ppc64le -mcpu=pwr8 -mattr=+altivec -mattr=-vsx | FileCheck %s
; RUN: llc < %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)