https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91758
--- Comment #3 from Martin Liška <marxin at gcc dot gnu.org> --- So that's what I have: 1) reduced LLVM test-case: $ cat /tmp/llvm-project/clang/test/CodeGen/lanai-regparm.c void f2(int a) __attribute((regparm(0))); void f0() { f2(1); } 2) I applied the following local patch to make the change smaller: diff --git a/clang/include/clang/CodeGen/CGFunctionInfo.h b/clang/include/clang/CodeGen/CGFunctionInfo.h index 1f81072e23d..ef7f7410c9b 100644 --- a/clang/include/clang/CodeGen/CGFunctionInfo.h +++ b/clang/include/clang/CodeGen/CGFunctionInfo.h @@ -87,14 +87,14 @@ private: unsigned AllocaFieldIndex; // isInAlloca() }; Kind TheKind; - bool PaddingInReg : 1; - bool InAllocaSRet : 1; // isInAlloca() - bool IndirectByVal : 1; // isIndirect() - bool IndirectRealign : 1; // isIndirect() - bool SRetAfterThis : 1; // isIndirect() + bool PaddingInReg; + bool InAllocaSRet; // isInAlloca() + bool IndirectByVal; // isIndirect() + bool CanBeFlattened; // isDirect() + bool SignExt ; // isExtend() + bool SRetAfterThis ; // isIndirect() + bool IndirectRealign: 1; // isIndirect() bool InReg : 1; // isDirect() || isExtend() || isIndirect() - bool CanBeFlattened: 1; // isDirect() - bool SignExt : 1; // isExtend() bool canHavePaddingType() const { return isDirect() || isExtend() || isIndirect() || isExpand(); diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index f2696a33cfb..b115d9da145 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -7567,7 +7567,10 @@ public: if (!getCXXABI().classifyReturnType(FI)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); for (auto &I : FI.arguments()) + { I.info = classifyArgumentType(I.type, State); + __builtin_printf ("after: I.info: %d\n", I.info.getInReg ()); + } } ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const; @@ -7658,7 +7661,9 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, } if (InReg) return ABIArgInfo::getDirectInReg(); - return ABIArgInfo::getDirect(); + ABIArgInfo ret = ABIArgInfo::getDirect(); + __builtin_printf ("before: %d\n", ret.getInReg ()); + return ret; } namespace { 3) I see the problematic file is: /tmp/llvm-project/clang/lib/CodeGen/TargetInfo.cpp 4) I took the patch from r261089 and applied it to r255894 and it still fails 5) apparently one needs -O3 to expose the issue 6) If I add following dbg_cnt: diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def index 0421fae7bc0..3830666dc6c 100644 --- a/gcc/dbgcnt.def +++ b/gcc/dbgcnt.def @@ -195,3 +195,4 @@ DEBUG_COUNTER (tree_sra) DEBUG_COUNTER (vect_loop) DEBUG_COUNTER (vect_slp) DEBUG_COUNTER (dom_unreachable_edges) +DEBUG_COUNTER (store_merging) diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 3c63e75fcf6..2369fd4bf5d 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -166,6 +166,7 @@ #include "rtl.h" #include "expr.h" /* For get_bit_range. */ #include "optabs-tree.h" +#include "dbgcnt.h" #include "selftest.h" /* The maximum size (in bits) of the stores this pass should generate. */ @@ -3898,7 +3899,8 @@ imm_store_chain_info::output_merged_stores () bool ret = false; FOR_EACH_VEC_ELT (m_merged_store_groups, i, merged_store) { - if (output_merged_store (merged_store)) + if (dbg_cnt (store_merging) + && output_merged_store (merged_store)) { unsigned int j; store_immediate_info *store; I can bisect that to one store merging transformation: before: MEM[(struct SmallVectorBase *)&Elements].Size = 0; MEM[(struct SmallVectorBase *)&Elements].Capacity = 3; after: MEM[(unsigned int *)&Elements + 8B] = 12884901888; if (SizeInRegs_144 > 3) The transformation looks fine to me and it must be an issue in RTL, because this is the only difference I see in tree optimized dump file. The change happens in {anonymous}::ARCABIInfo::computeInfo (const struct ARCABIInfo * const this, struct CGFunctionInfo & FI) function. And the valgrind also points to the same function: valgrind /tmp/llvm-project/build/bin/clang -cc1 -triple lanai-unknown-unknown -mregparm 4 /tmp/llvm-project/clang/test/CodeGen/lanai-regparm.c -emit-llvm ==766== Memcheck, a memory error detector ==766== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==766== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==766== Command: /tmp/llvm-project/build/bin/clang -cc1 -triple lanai-unknown-unknown -mregparm 4 /tmp/llvm-project/clang/test/CodeGen/lanai-regparm.c -emit-llvm ==766== before: 0 ==766== Conditional jump or move depends on uninitialised value(s) ==766== at 0x7295287: __vfprintf_internal (vfprintf-internal.c:1644) ==766== by 0x7280C7A: printf (printf.c:33) ==766== by 0x2776A28: (anonymous namespace)::LanaiABIInfo::computeInfo(clang::CodeGen::CGFunctionInfo&) const (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x27F7533: clang::CodeGen::CodeGenTypes::arrangeLLVMFunctionInfo(clang::CanQual<clang::Type>, bool, bool, llvm::ArrayRef<clang::CanQual<clang::Type> >, clang::FunctionType::ExtInfo, llvm::ArrayRef<clang::FunctionType::ExtParameterInfo>, clang::CodeGen::RequiredArgs) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x27F9D94: clang::CodeGen::CodeGenTypes::arrangeFreeFunctionType(clang::CanQual<clang::FunctionProtoType>) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x272AAC9: clang::CodeGen::CodeGenTypes::ConvertFunctionTypeInternal(clang::QualType) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x272BD45: clang::CodeGen::CodeGenTypes::ConvertType(clang::QualType) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x2701D5A: clang::CodeGen::CodeGenModule::GetAddrOfFunction(clang::GlobalDecl, llvm::Type*, bool, bool, clang::CodeGen::ForDefinition_t) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x28472E2: EmitFunctionDeclPointer(clang::CodeGen::CodeGenModule&, clang::FunctionDecl const*) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x2861F2C: clang::CodeGen::CodeGenFunction::EmitCallee(clang::Expr const*) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x28621F2: clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) (in /tmp/llvm-project/build/bin/clang-10) ==766== by 0x2897478: (anonymous namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) (in /tmp/llvm-project/build/bin/clang-10) 7) The wrong output is then: marxin@marxinbox:/tmp/llvm-project/build> /tmp/llvm-project/build/bin/clang -cc1 -triple lanai-unknown-unknown -mregparm 4 /tmp/llvm-project/clang/test/CodeGen/lanai-regparm.c -emit-llvm before: 0 after: I.info: 1 marxin@marxinbox:/tmp/llvm-project/build> /tmp/llvm-project/build/bin/clang -cc1 -triple lanai-unknown-unknown -mregparm 4 /tmp/llvm-project/clang/test/CodeGen/lanai-regparm.c -emit-llvm before: 0 after: I.info: 0 So I.info.getInReg() is sometimes 0 and sometimes 1. I'm going to carry on ..