[cfe-dev] question regarding the C++ test case under LLVM test

Lin, Jin via cfe-dev cfe-dev at lists.llvm.org
Tue Sep 20 17:16:36 PDT 2016



-----Original Message-----
From: Jonathan Roelofs [mailto:jonathan at codesourcery.com] 
Sent: Tuesday, September 20, 2016 3:33 PM
To: Lin, Jin <jin.lin at intel.com>; cfe-dev at lists.llvm.org
Subject: Re: [cfe-dev] question regarding the C++ test case under LLVM test



On 9/20/16 4:15 PM, Lin, Jin wrote:
> I think a better solution is to extend the utility llvm-lit to process 
> the -target  option. If the target option and the host match, the 
> script will be executed. Otherwise just ignore the test case.
> What do you think?

That's actually not better.

The problem you're going to run into is that your host system's headers are leaking into a target test. Now you have a testcase that could pass on one machine, but fail on another (even if they're both linux machines). The buildbots are very good at noticing this kind of thing because they all run on different host platforms.

If you look through Clang's codegen tests, you'll find that none of them include anything from the host system... that is not an accident. It was done very purposefully: all of the codegen tests should behave precisely the same, no matter what the host platform is, and no matter what versions of libc/libm/c++ standard library/etc are installed.

There are solutions to the specific questions you're asking (about how to prevent a testcase from running on a specific platform), but I'm avoiding telling you them because I think they're solving the wrong problem (specifically, this is a case of an XY problem:
http://http://xyproblem.info/).


*************
The purpose of my test is to check whether the clang generates the new intrinsic for STL containers such as vector. 

Here is the LLVM IR of the vector constructor under Linux and windows.  We can see that the LLVM IR are different. In order to instrument the new Intrinsic correctly, the clang has to call the utility getTarget().getTriple().isKnownWindowsMSVCEnvironment() to understand the OS and perform different action. 

For the STL iterator, it is more complicated. Under Linux it is in gnucxx namespace and under Windows it is in std namespace.

Let's assume I create a file with minimal version of std::vector. Now the question which version (windows/linux) should I include.  One of them will definitely fail if the script is blindly executed under Linux and Windows. 

Do you have any good suggestions?

Thanks,

Jin

Linux version:
 define linkonce_odr dereferenceable(4) float* @_ZNSt6vectorIfSaIfEEixEm(%"class.std::vector"* %this, i64 %__n) #3 comdat align 2 {
 entry:
  %this.addr = alloca %"class.std::vector"*, align 8
  %__n.addr = alloca i64, align 8
  store %"class.std::vector"* %this, %"class.std::vector"** %this.addr,align 8, !tbaa !10
  store i64 %__n, i64* %__n.addr, align 8, !tbaa !12
  %this1 = load %"class.std::vector"*, %"class.std::vector"** %this.addr, align 8
  %0 = bitcast %"class.std::vector"* %this1 to %"struct.std::_Vector_base"*  %_M_impl = getelementptr inbounds %"struct.std::_Vector_base", %"struct.std::_Vector_base"* %0, i32 0, i32 0
  %_M_start = getelementptr inbounds %"struct.std::_Vector_base<float,  std::allocator<float> >::_Vector_impl", %"struct.std::_Vector_base<
  float, std::allocator<float> >::_Vector_impl"* %_M_impl, i32 0, i32 0
  %1 = call float** @llvm.std.container.ptr.p0p0f32(float**  %_M_start) #1
  %2 = load float*, float** %1, align 8, !tbaa !1
  %3 = load i64, i64* %__n.addr, align 8, !tbaa !12
  %add.ptr = getelementptr inbounds float, float* %2, i64 %3
  ret float* %add.ptr
}


 Windows version
 define linkonce_odr dereferenceable(4) float* @"\01??A?$vector at MV?$allocator at M@std@@@std@@QEAAAEAM_K at Z"(%"class.std::vector"* %this, i64 %_Pos) #0 comdat align 2 {
 entry:
  %_Pos.addr = alloca i64, align 8
  %this.addr = alloca %"class.std::vector"*, align 8
  store i64 %_Pos, i64* %_Pos.addr, align 8, !tbaa !19
  store %"class.std::vector"* %this, %"class.std::vector"** %this.addr, align 8, !tbaa !21
  %this1 = load %"class.std::vector"*, %"class.std::vector"** %this.addr,  align8
  %0 = bitcast %"class.std::vector"* %this1 to %"class.std::_Vector_val"*
  %_Myfirst = getelementptr inbounds %"class.std::_Vector_val", %"class.std::_Vector_val"* %0, i32 0, i32 0
  %1 = call float** @llvm.std.container.ptr.p0p0f32(float**  %_Myfirst) #1
  %2 = load float*, float** %1, align 8, !tbaa !23
  %3 = load i64, i64* %_Pos.addr, align 8, !tbaa !19
  %add.ptr = getelementptr inbounds float, float* %2, i64 %3
  ret float* %add.ptr





Jon

>
> Thanks,
>
> Jin
>

--
Jon Roelofs
jonathan at codesourcery.com
CodeSourcery / Mentor Embedded


More information about the cfe-dev mailing list