From fd7429c4e7bf65aa691380a35dcc5732e5a10212 Mon Sep 17 00:00:00 2001 From: Daniel Cederman Date: Mon, 16 Jul 2018 12:14:17 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337161 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/LegalizeTypesGeneric.cpp | 3 ++- test/CodeGen/SPARC/varargs-v8.ll | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/SPARC/varargs-v8.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index de0f2aa32f4..df3134828af 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -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); } diff --git a/test/CodeGen/SPARC/varargs-v8.ll b/test/CodeGen/SPARC/varargs-v8.ll new file mode 100644 index 00000000000..2af12547b3f --- /dev/null +++ b/test/CodeGen/SPARC/varargs-v8.ll @@ -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 +} -- 2.50.1