Avoid losing Hi part when expanding VAARG nodes on big endian machines

Summary:
If the high part of the load is not used the offset to the next element
will not be set correctly.

For example, on Sparc V8, the following code will read val2 from offset 4
instead of 8.

```
int val = __builtin_va_arg(va, long long);
int val2 = __builtin_va_arg(va, int);
```

Reviewers: jyknight

Reviewed By: jyknight

Subscribers: fedor.sergeev, jrtc27, llvm-commits

Differential Revision: https://reviews.llvm.org/D48595

llvm-svn: 337161
This commit is contained in:
Daniel Cederman 2018-07-16 12:14:17 +00:00
parent e66a6f48e3
commit c3d8002c2e
2 changed files with 26 additions and 1 deletions

View File

@ -300,6 +300,7 @@ void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align);
Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0);
Chain = Hi.getValue(1);
// Handle endianness of the load.
if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout()))
@ -307,7 +308,7 @@ void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
// Modified the chain - switch anything that used the old chain to use
// the new one.
ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
ReplaceValueWith(SDValue(N, 1), Chain);
}

View File

@ -0,0 +1,24 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=sparc -disable-sparc-leaf-proc | FileCheck %s
define i32 @test(i32 %a, i8* %va) nounwind {
; CHECK-LABEL: test:
; CHECK: ! %bb.0: ! %entry
; CHECK-NEXT: save %sp, -96, %sp
; CHECK-NEXT: add %i1, 8, %i0
; CHECK-NEXT: st %i0, [%fp+-4]
; CHECK-NEXT: ld [%i1+4], %i0
; CHECK-NEXT: add %i1, 12, %i2
; CHECK-NEXT: st %i2, [%fp+-4]
; CHECK-NEXT: ld [%i1+8], %i1
; CHECK-NEXT: ret
; CHECK-NEXT: restore %i1, %i0, %o0
entry:
%va.addr = alloca i8*, align 4
store i8* %va, i8** %va.addr, align 4
%0 = va_arg i8** %va.addr, i64
%conv1 = trunc i64 %0 to i32
%1 = va_arg i8** %va.addr, i32
%add3 = add nsw i32 %1, %conv1
ret i32 %add3
}