[PATCH] D49754: Add -m(no-)spe, and e500 CPU definitions and support to clang

vit9696 via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 31 18:43:54 PDT 2018


vit9696 added a comment.

Hello,

Thank you for working this. I tried the change and have a couple of suggestions:

1. -mspe option in GCC works like -mspe=yes or -mspe=no. While it does make sense to have it the way you did (-mno-spe and -mspe) it would be nice to have at least have an alias for compiler compatibility.
2. One of the known CPU examples with SPE support is MPC8548 (https://www.nxp.com/docs/en/reference-manual/MPC8548ERM.pdf), it will be nice to have it recognised in -mcpu argument as 8548 like in GCC.

Other than that, it appears that the implementation has several issues. Since this patch is partially unmerged yet, I did not use bugzilla but include the information below.

1. The following code makes the compiler to crash:

  struct a {
    long double b() const;
  };
  class c {
    struct C {
      C(long d) : e(d) {}
      long e;
      double f;
    };
    unsigned g;
    C h[5];
    unsigned i;
    void k(C d) {
      long j(g);
      if (j)
        h[i] = d;
    }
    c &fn(const a &);
  };
  c &c::fn(const a &d) {
    double l = d.b();
    k(l);
  }



  $ clang-7 -cc1 -triple powerpc-gnu-linux-eabi -emit-obj -target-cpu ppc -target-feature +spe -O2  t.cpp
  t.cpp:23:1: warning: control reaches end of non-void function
  }
  ^
  Stack dump:
  0.	Program arguments: clang-7 -cc1 -triple powerpc-gnu-linux-eabi -emit-obj -target-cpu ppc -target-feature +spe -O2 t.cpp 
  1.	<eof> parser at end of file
  2.	Code generation
  3.	Running pass 'Function Pass Manager' on module 't.cpp'.
  4.	Running pass 'PowerPC DAG->DAG Pattern Instruction Selection' on function '@_ZN1c2fnERK1a'
  0  clang-7                  0x000000010a6e722d llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
  1  clang-7                  0x000000010a6e760d SignalHandler(int) + 185
  2  libsystem_platform.dylib 0x00007fff6a4baf5a _sigtramp + 26
  3  clang-7                  0x000000010ac4948a llvm::DenseMapBase<llvm::SmallDenseMap<unsigned int, unsigned int, 8u, llvm::DenseMapInfo<unsigned int>, llvm::detail::DenseMapPair<unsigned int, unsigned int> >, unsigned int, unsigned int, llvm::DenseMapInfo<unsigned int>, llvm::detail::DenseMapPair<unsigned int, unsigned int> >::find(unsigned int const&) + 18
  4  clang-7                  0x000000010ac3e23e llvm::DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(llvm::SDNode*, llvm::SDValue&, llvm::SDValue&) + 514
  5  clang-7                  0x000000010ac3a670 llvm::DAGTypeLegalizer::ExpandIntegerResult(llvm::SDNode*, unsigned int) + 1774
  6  clang-7                  0x000000010ac49793 llvm::DAGTypeLegalizer::run() + 531
  7  clang-7                  0x000000010ac4c1cd llvm::SelectionDAG::LegalizeTypes() + 57
  8  clang-7                  0x000000010acde3da llvm::SelectionDAGISel::CodeGenAndEmitDAG() + 468
  9  clang-7                  0x000000010acdd8a9 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 5521
  10 clang-7                  0x000000010acdbbc9 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 1433
  11 clang-7                  0x0000000109e18962 (anonymous namespace)::PPCDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 70
  12 clang-7                  0x000000010a20d353 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 113
  13 clang-7                  0x000000010a393af4 llvm::FPPassManager::runOnFunction(llvm::Function&) + 338
  14 clang-7                  0x000000010a393c89 llvm::FPPassManager::runOnModule(llvm::Module&) + 49
  15 clang-7                  0x000000010a393f66 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 556
  16 clang-7                  0x000000010a81a77b clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream> >) + 13071
  17 clang-7                  0x000000010a97e61c clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) + 888
  18 clang-7                  0x000000010b14479c clang::ParseAST(clang::Sema&, bool, bool) + 458
  19 clang-7                  0x000000010aaff2b9 clang::FrontendAction::Execute() + 67
  20 clang-7                  0x000000010aad1ac0 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 664
  21 clang-7                  0x000000010ab3352c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1267
  22 clang-7                  0x0000000109c49f00 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 1138
  23 clang-7                  0x0000000109c4923d main + 7612
  24 libdyld.dylib            0x00007fff6a1ac015 start + 1
  25 libdyld.dylib            0x000000000000000b start + 2514829303
  Segmentation fault: 11



2. Several instructions seem to fail at variable allocation due to improper type. For example, the following code will overwrite the variables on stack and crash:

  int global_var1;
  
  void test_func2(void) { }
  
  void test_func(int a1, long long a2, void *a3, int *a4, int *a5) {
      int *ptr = &global_var1;
  
      if (ptr != 0) {
          volatile int v1[6] = {};
          *a5 = 0;
          test_func2();
          volatile int v2[5] = {};
      } else {
          volatile int v3[3] = {};
          *a5 = 0;
      }
  }
  
  void main(void) {
      int ret;
      test_func(0, 0, 0, 0, &ret);
  }

The assembly generated is as follows:

  $ clang -S -o main.S -c -target powerpc-gnu-linux-eabi -mcpu=e500 -mspe main.c
  .Lfunc_begin1:
  # %bb.0:
  	mflr 0
  	stw 0, 4(1)
  	stwu 1, -288(1)
  	stw 31, 284(1)
  	mr 31, 1
  	stw 30, 280(31)                 # 4-byte Folded Spill
  	evstdd 14, 128(31)              # 8-byte Folded Spill
  	evstdd 15, 136(31)              # 8-byte Folded Spill
  	evstdd 16, 144(31)              # 8-byte Folded Spill
  	evstdd 17, 152(31)              # 8-byte Folded Spill
  	evstdd 18, 160(31)              # 8-byte Folded Spill
  	evstdd 19, 168(31)              # 8-byte Folded Spill
  	evstdd 20, 176(31)              # 8-byte Folded Spill
  	evstdd 21, 184(31)              # 8-byte Folded Spill
  	evstdd 22, 192(31)              # 8-byte Folded Spill
  	evstdd 23, 200(31)              # 8-byte Folded Spill
  	evstdd 24, 208(31)              # 8-byte Folded Spill
  	evstdd 25, 216(31)              # 8-byte Folded Spill
  	evstdd 26, 224(31)              # 8-byte Folded Spill
  	evstdd 27, 232(31)              # 8-byte Folded Spill
  	evstdd 28, 240(31)              # 8-byte Folded Spill
  	evstdd 29, 248(31)              # 8-byte Folded Spill
  	evstdd 30, 256(31)              # 8-byte Folded Spill
  	evstdd 31, 264(31)              # 8-byte Folded Spill
  …

The offset wraps around and what is actually encoded for the last two instructions is effectively:

  evstdd 30, 0(31)
  evstdd 30, 8(31)

Hope this helps,
Vit


Repository:
  rC Clang

https://reviews.llvm.org/D49754





More information about the cfe-commits mailing list