Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -2277,6 +2277,18 @@ /// Heuristically search for a dominating store to the return-value slot. static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { + // Check if a User is a store which pointerOperand is the ReturnValue. + // We are looking for stores to the ReturnValue, not for stores of the + // ReturnValue to some other location. + auto getStoreIfValid = [&CGF](llvm::User *U) -> llvm::StoreInst * { + auto *SI = dyn_cast(U); + if (!SI || SI->getPointerOperand() != CGF.ReturnValue) + return nullptr; + // These aren't actually possible for non-coerced returns, and we + // only care about non-coerced returns on this code path. + assert(!SI->isAtomic() && !SI->isVolatile()); + return SI; + }; // If there are multiple uses of the return-value slot, just check // for something immediately preceding the IP. Sometimes this can // happen with how we generate implicit-returns; it can also happen @@ -2305,21 +2317,12 @@ break; } - llvm::StoreInst *store = dyn_cast(I); - if (!store) return nullptr; - if (store->getPointerOperand() != CGF.ReturnValue) return nullptr; - assert(!store->isAtomic() && !store->isVolatile()); // see below - return store; + return getStoreIfValid(I); } - llvm::StoreInst *store = - dyn_cast(CGF.ReturnValue->user_back()); + llvm::StoreInst *store = getStoreIfValid(CGF.ReturnValue->user_back()); if (!store) return nullptr; - // These aren't actually possible for non-coerced returns, and we - // only care about non-coerced returns on this code path. - assert(!store->isAtomic() && !store->isVolatile()); - // Now do a first-and-dirty dominance check: just walk up the // single-predecessors chain from the current insertion point. llvm::BasicBlock *StoreBB = store->getParent(); Index: test/CodeGen/arm_function_epilog.cpp =================================================================== --- /dev/null +++ test/CodeGen/arm_function_epilog.cpp @@ -0,0 +1,17 @@ +// REQUIRES: arm-registered-target +// RUN: %clang_cc1 -triple armv7-none-linux-androideabi -target-abi aapcs-linux -mfloat-abi hard -x c++ -emit-llvm %s -o - | FileCheck %s + +struct Vec2 { + union { struct { float x, y; }; + float data[2]; + }; +}; + +// CHECK: define arm_aapcs_vfpcc %struct.Vec2 @_Z7getVec2v() +// CHECK: ret %struct.Vec2 +Vec2 getVec2() { + Vec2 out; + union { Vec2* v; unsigned char* u; } x; + x.v = &out; + return out; +}