OSDN Git Service

Avoid output indeterminism between GCC and Clang builds.
authorPatrik Hagglund <patrik.h.hagglund@ericsson.com>
Mon, 20 Jun 2016 10:19:00 +0000 (10:19 +0000)
committerPatrik Hagglund <patrik.h.hagglund@ericsson.com>
Mon, 20 Jun 2016 10:19:00 +0000 (10:19 +0000)
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

index cbe3686..830b23c 100644 (file)
@@ -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");
     }