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 ..

Reply via email to