From 44907069dab7a0aa0850b08f6f27fa83aeaa5cd2 Mon Sep 17 00:00:00 2001 From: Patrik Hagglund Date: Mon, 20 Jun 2016 10:19:00 +0000 Subject: [PATCH] Avoid output indeterminism between GCC and Clang builds. Remove dependency of the evalution order of function arguments, which is unspecified. The following test previously failed when built with GCC (but succeded when built with Clang): ; RUN: opt -sroa -S < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" %A = type {i16} @a = global %A* null @b = global i16 0 ; CHECK-LABEL: @f1( ; CHECK: alloca %A ; CHECK-NEXT: extractvalue %A ; CHECK-NEXT: getelementptr inbounds %A define void @f1 (%A %a) { %1 = alloca %A store %A %a, %A* %1 %2 = load i16, i16* @b %3 = icmp ne i16 %2, 0 br i1 %3, label %bb1, label %bb2 bb1: store %A* %1, %A** @a br label %bb2 bb2: ret void } Patch by David Stenberg. Differential Revision: http://reviews.llvm.org/D21226 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273144 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SROA.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index cbe36861a67..830b23c4bff 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -3107,9 +3107,14 @@ private: void emitFunc(Type *Ty, Value *&Agg, const Twine &Name) { assert(Ty->isSingleValueType()); // Extract the single value and store it using the indices. - Value *Store = IRB.CreateStore( - IRB.CreateExtractValue(Agg, Indices, Name + ".extract"), - IRB.CreateInBoundsGEP(nullptr, Ptr, GEPIndices, Name + ".gep")); + // + // The gep and extractvalue values are factored out of the CreateStore + // call to make the output independent of the argument evaluation order. + Value *ExtractValue = IRB.CreateExtractValue(Agg, Indices, + Name + ".extract"); + Value *InBoundsGEP = IRB.CreateInBoundsGEP(nullptr, Ptr, GEPIndices, + Name + ".gep"); + Value *Store = IRB.CreateStore(ExtractValue, InBoundsGEP); (void)Store; DEBUG(dbgs() << " to: " << *Store << "\n"); } -- 2.50.1