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

Lin, Jin via cfe-dev cfe-dev at lists.llvm.org
Wed Sep 21 19:47:46 PDT 2016



-----Original Message-----
From: Jonathan Roelofs [mailto:jonathan at codesourcery.com] 
Sent: Wednesday, September 21, 2016 7:07 AM
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 6:16 PM, Lin, Jin wrote:
>
>
> -----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.

This ^ depends entirely on the '-target' triple, and not at all on the host.

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

Which one you use should depend only on the _target_ triple, and not at all on the _host_.

If you want to stick them in the same file, the preprocessor can be a good way to do that:

// RUN: %clangxx -target i686-pc-linux-gnu ... -DLINUX_32 | FileCheck %s // RUN: %clangxx -target x86_64-pc-mingw32 ... -DWIN_32 | FileCheck %s

#if defined(LINUX_32)
   // linux-specific version of the stuff you want to test #elif defined(WIN_32)
   // windows-specific version of the stuff you want to test #endif

That is very good suggestions. At least it works for my case. 

My concern here is that the code size of test case may increase a lot if we keep adding new OS or platform support by following this approach. 

Thanks,

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

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


More information about the cfe-dev mailing list