mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
c274d8aae7
The PPCTargetLowering::SelectAddressRegImm routine needs to handle FrameIndex nodes in a special manner, by tranlating them into a TargetFrameIndex node. This was done in most cases, but seems to have been neglected in one path: when the input tree has an OR of the FrameIndex with an immediate. This can happen if the FrameIndex can be proven to be sufficiently aligned that an OR of that immediate is equivalent to an ADD. The missing handling of FrameIndex in that case caused the SelectionDAG instruction selection to miss opportunities to merge the OR back into the FrameIndex node, leading to superfluous addi/ori instructions in the final assembler output. llvm-svn: 213482
182 lines
5.9 KiB
LLVM
182 lines
5.9 KiB
LLVM
; RUN: llc -O0 -mcpu=ppc64 -mtriple=powerpc64-unknown-linux-gnu -fast-isel=false < %s | FileCheck %s
|
|
; RUN: llc -O0 -mcpu=g4 -mtriple=powerpc-apple-darwin8 < %s | FileCheck -check-prefix=DARWIN32 %s
|
|
; RUN: llc -O0 -mcpu=ppc970 -mtriple=powerpc64-apple-darwin8 < %s | FileCheck -check-prefix=DARWIN64 %s
|
|
|
|
; Test case for PR 14779: anonymous aggregates are not handled correctly.
|
|
; Darwin bug report PR 15821 is similar.
|
|
; The bug is triggered by passing a byval structure after an anonymous
|
|
; aggregate.
|
|
|
|
%tarray = type { i64, i8* }
|
|
|
|
define i8* @func1({ i64, i8* } %array, i8* %ptr) {
|
|
entry:
|
|
%array_ptr = extractvalue {i64, i8* } %array, 1
|
|
%cond = icmp eq i8* %array_ptr, %ptr
|
|
br i1 %cond, label %equal, label %unequal
|
|
equal:
|
|
ret i8* %array_ptr
|
|
unequal:
|
|
ret i8* %ptr
|
|
}
|
|
|
|
; CHECK-LABEL: func1:
|
|
; CHECK: cmpld {{[0-9]+}}, 4, 5
|
|
; CHECK-DAG: std 4, -[[OFFSET1:[0-9]+]]
|
|
; CHECK-DAG: std 5, -[[OFFSET2:[0-9]+]]
|
|
; CHECK: ld 3, -[[OFFSET1]](1)
|
|
; CHECK: ld 3, -[[OFFSET2]](1)
|
|
|
|
; DARWIN32: _func1:
|
|
; DARWIN32: mr
|
|
; DARWIN32: mr r[[REG1:[0-9]+]], r[[REGA:[0-9]+]]
|
|
; DARWIN32: mr r[[REG2:[0-9]+]], r[[REGB:[0-9]+]]
|
|
; DARWIN32: cmplw cr{{[0-9]+}}, r[[REGA]], r[[REGB]]
|
|
; DARWIN32: stw r[[REG1]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN32: stw r[[REG2]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN32: lwz r3, -[[OFFSET1]]
|
|
; DARWIN32: lwz r3, -[[OFFSET2]]
|
|
|
|
; DARWIN64: _func1:
|
|
; DARWIN64: mr
|
|
; DARWIN64: mr r[[REG1:[0-9]+]], r[[REGA:[0-9]+]]
|
|
; DARWIN64: mr r[[REG2:[0-9]+]], r[[REGB:[0-9]+]]
|
|
; DARWIN64: cmpld cr{{[0-9]+}}, r[[REGA]], r[[REGB]]
|
|
; DARWIN64: std r[[REG1]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN64: std r[[REG2]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN64: ld r3, -[[OFFSET1]]
|
|
; DARWIN64: ld r3, -[[OFFSET2]]
|
|
|
|
|
|
define i8* @func2({ i64, i8* } %array1, %tarray* byval %array2) {
|
|
entry:
|
|
%array1_ptr = extractvalue {i64, i8* } %array1, 1
|
|
%tmp = getelementptr inbounds %tarray* %array2, i32 0, i32 1
|
|
%array2_ptr = load i8** %tmp
|
|
%cond = icmp eq i8* %array1_ptr, %array2_ptr
|
|
br i1 %cond, label %equal, label %unequal
|
|
equal:
|
|
ret i8* %array1_ptr
|
|
unequal:
|
|
ret i8* %array2_ptr
|
|
}
|
|
|
|
; CHECK-LABEL: func2:
|
|
; CHECK: ld [[REG2:[0-9]+]], 72(1)
|
|
; CHECK: cmpld {{[0-9]+}}, 4, [[REG2]]
|
|
; CHECK-DAG: std [[REG2]], -[[OFFSET1:[0-9]+]]
|
|
; CHECK-DAG: std 4, -[[OFFSET2:[0-9]+]]
|
|
; CHECK: ld 3, -[[OFFSET2]](1)
|
|
; CHECK: ld 3, -[[OFFSET1]](1)
|
|
|
|
; DARWIN32: _func2:
|
|
; DARWIN32: addi r[[REG1:[0-9]+]], r[[REGSP:[0-9]+]], 36
|
|
; DARWIN32: lwz r[[REG2:[0-9]+]], 44(r[[REGSP]])
|
|
; DARWIN32: mr
|
|
; DARWIN32: mr r[[REG3:[0-9]+]], r[[REGA:[0-9]+]]
|
|
; DARWIN32: cmplw cr{{[0-9]+}}, r[[REGA]], r[[REG2]]
|
|
; DARWIN32: stw r[[REG3]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN32: stw r[[REG2]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN32: lwz r3, -[[OFFSET1]]
|
|
; DARWIN32: lwz r3, -[[OFFSET2]]
|
|
|
|
; DARWIN64: _func2:
|
|
; DARWIN64: ld r[[REG2:[0-9]+]], 72(r1)
|
|
; DARWIN64: mr
|
|
; DARWIN64: mr r[[REG3:[0-9]+]], r[[REGA:[0-9]+]]
|
|
; DARWIN64: cmpld cr{{[0-9]+}}, r[[REGA]], r[[REG2]]
|
|
; DARWIN64: std r[[REG3]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN64: std r[[REG2]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN64: ld r3, -[[OFFSET1]]
|
|
; DARWIN64: ld r3, -[[OFFSET2]]
|
|
|
|
|
|
define i8* @func3({ i64, i8* }* byval %array1, %tarray* byval %array2) {
|
|
entry:
|
|
%tmp1 = getelementptr inbounds { i64, i8* }* %array1, i32 0, i32 1
|
|
%array1_ptr = load i8** %tmp1
|
|
%tmp2 = getelementptr inbounds %tarray* %array2, i32 0, i32 1
|
|
%array2_ptr = load i8** %tmp2
|
|
%cond = icmp eq i8* %array1_ptr, %array2_ptr
|
|
br i1 %cond, label %equal, label %unequal
|
|
equal:
|
|
ret i8* %array1_ptr
|
|
unequal:
|
|
ret i8* %array2_ptr
|
|
}
|
|
|
|
; CHECK-LABEL: func3:
|
|
; CHECK: ld [[REG3:[0-9]+]], 72(1)
|
|
; CHECK: ld [[REG4:[0-9]+]], 56(1)
|
|
; CHECK: cmpld {{[0-9]+}}, [[REG4]], [[REG3]]
|
|
; CHECK: std [[REG3]], -[[OFFSET1:[0-9]+]](1)
|
|
; CHECK: std [[REG4]], -[[OFFSET2:[0-9]+]](1)
|
|
; CHECK: ld 3, -[[OFFSET2]](1)
|
|
; CHECK: ld 3, -[[OFFSET1]](1)
|
|
|
|
; DARWIN32: _func3:
|
|
; DARWIN32: addi r[[REG1:[0-9]+]], r[[REGSP:[0-9]+]], 36
|
|
; DARWIN32: addi r[[REG2:[0-9]+]], r[[REGSP]], 24
|
|
; DARWIN32: lwz r[[REG3:[0-9]+]], 44(r[[REGSP]])
|
|
; DARWIN32: lwz r[[REG4:[0-9]+]], 32(r[[REGSP]])
|
|
; DARWIN32: cmplw cr{{[0-9]+}}, r[[REG4]], r[[REG3]]
|
|
; DARWIN32: stw r[[REG3]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN32: stw r[[REG4]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN32: lwz r3, -[[OFFSET2]]
|
|
; DARWIN32: lwz r3, -[[OFFSET1]]
|
|
|
|
; DARWIN64: _func3:
|
|
; DARWIN64: ld r[[REG3:[0-9]+]], 72(r1)
|
|
; DARWIN64: ld r[[REG4:[0-9]+]], 56(r1)
|
|
; DARWIN64: cmpld cr{{[0-9]+}}, r[[REG4]], r[[REG3]]
|
|
; DARWIN64: std r[[REG3]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN64: std r[[REG4]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN64: ld r3, -[[OFFSET2]]
|
|
; DARWIN64: ld r3, -[[OFFSET1]]
|
|
|
|
|
|
define i8* @func4(i64 %p1, i64 %p2, i64 %p3, i64 %p4,
|
|
i64 %p5, i64 %p6, i64 %p7, i64 %p8,
|
|
{ i64, i8* } %array1, %tarray* byval %array2) {
|
|
entry:
|
|
%array1_ptr = extractvalue {i64, i8* } %array1, 1
|
|
%tmp = getelementptr inbounds %tarray* %array2, i32 0, i32 1
|
|
%array2_ptr = load i8** %tmp
|
|
%cond = icmp eq i8* %array1_ptr, %array2_ptr
|
|
br i1 %cond, label %equal, label %unequal
|
|
equal:
|
|
ret i8* %array1_ptr
|
|
unequal:
|
|
ret i8* %array2_ptr
|
|
}
|
|
|
|
; CHECK-LABEL: func4:
|
|
; CHECK: ld [[REG3:[0-9]+]], 136(1)
|
|
; CHECK: ld [[REG2:[0-9]+]], 120(1)
|
|
; CHECK: cmpld {{[0-9]+}}, [[REG2]], [[REG3]]
|
|
; CHECK: std [[REG3]], -[[OFFSET2:[0-9]+]](1)
|
|
; CHECK: std [[REG2]], -[[OFFSET1:[0-9]+]](1)
|
|
; CHECK: ld 3, -[[OFFSET1]](1)
|
|
; CHECK: ld 3, -[[OFFSET2]](1)
|
|
|
|
; DARWIN32: _func4:
|
|
; DARWIN32: lwz r[[REG4:[0-9]+]], 96(r1)
|
|
; DARWIN32: addi r[[REG1:[0-9]+]], r1, 100
|
|
; DARWIN32: lwz r[[REG3:[0-9]+]], 108(r1)
|
|
; DARWIN32: mr r[[REG2:[0-9]+]], r[[REG4]]
|
|
; DARWIN32: cmplw cr{{[0-9]+}}, r[[REG4]], r[[REG3]]
|
|
; DARWIN32: stw r[[REG4]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN32: stw r[[REG3]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN32: lwz r[[REG1]], -[[OFFSET1]]
|
|
; DARWIN32: lwz r[[REG1]], -[[OFFSET2]]
|
|
|
|
; DARWIN64: _func4:
|
|
; DARWIN64: ld r[[REG2:[0-9]+]], 120(r1)
|
|
; DARWIN64: ld r[[REG3:[0-9]+]], 136(r1)
|
|
; DARWIN64: mr r[[REG4:[0-9]+]], r[[REG2]]
|
|
; DARWIN64: cmpld cr{{[0-9]+}}, r[[REG2]], r[[REG3]]
|
|
; DARWIN64: std r[[REG4]], -[[OFFSET1:[0-9]+]]
|
|
; DARWIN64: std r[[REG3]], -[[OFFSET2:[0-9]+]]
|
|
; DARWIN64: ld r3, -[[OFFSET1]]
|
|
; DARWIN64: ld r3, -[[OFFSET2]]
|