cdl-saarland / rv

RV: A Unified Region Vectorizer for LLVM
Other
100 stars 15 forks source link

[MCE] common type too low #23

Open Commaster opened 5 years ago

Commaster commented 5 years ago
-- memCopy elision log --
Found divergent memcpy:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %11, i8* %12, i64 16, i32 4, i1 false), !tbaa.struct !12
derive   %arrayidx7.prol.i.i = getelementptr inbounds %struct.FOUR_VECTOR, %struct.FOUR_VECTOR* %callable.coerce3, i64 %10 size 16
        hit: pointer aligns with type!
derive   %arrayidx9.prol.i.i = getelementptr inbounds [100 x %struct.FOUR_VECTOR], [100 x %struct.FOUR_VECTOR]* @_ZZ6kernelIN5pacxx2v25rangeEEvRT_7par_str7dim_strP7box_strP11FOUR_VECTORPfSA_E9rA_shared, i64 0, i64 %indvars.iv245.prol.i.i size 16
        hit: pointer aligns with type!
                 derive common type for %struct.FOUR_VECTOR = type { float, float, float, float } and %struct.FOUR_VECTOR = type { float, float, float, float }
                 derive common type for float and %struct.FOUR_VECTOR = type { float, float, float, float }
                 derive common type for float and float
        skip: common base type: float
[llvm] CreateGEP called
[llvm] General case
[llvm] Values: 3
[llvm] PointeeType is nullptr, replacing
[llvm] Base type: %struct.FOUR_VECTOR*, ScalarPointerType: %struct.FOUR_VECTOR*, ElementType: %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] Resulting type: %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] Getting GEP Return Type from Type: %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] Getting IndexedType for %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] is sized
[llvm] is composite
[llvm] Verifying index
[llvm] Refreshing Type
[llvm] Type refreshed to float
[llvm] Idx 2 size 2
[llvm] not nullptr
[llvm] Getting IndexedType for %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] is sized
[llvm] is composite
[llvm] Verifying index
[llvm] Refreshing Type
[llvm] Type refreshed to float
[llvm] Idx 2 size 2
[llvm] CreateGEP called
[llvm] General case
[llvm] Values: 3
[llvm] PointeeType is nullptr, replacing
[llvm] Base type: %struct.FOUR_VECTOR*, ScalarPointerType: %struct.FOUR_VECTOR*, ElementType: %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] Resulting type: %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] Getting GEP Return Type from Type: %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] Getting IndexedType for %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] is sized
[llvm] is composite
[llvm] Verifying index
[llvm] Refreshing Type
[llvm] Type refreshed to float
[llvm] Idx 2 size 2
[llvm] not nullptr
[llvm] Getting IndexedType for %struct.FOUR_VECTOR = type { float, float, float, float }
[llvm] is sized
[llvm] is composite
[llvm] Verifying index
[llvm] Refreshing Type
[llvm] Type refreshed to float
[llvm] Idx 2 size 2
OK base gep src:   %basegep = getelementptr %struct.FOUR_VECTOR, %struct.FOUR_VECTOR* %arrayidx7.prol.i.i, i32 0, i32 0   base gep dest:   %basegep27 = getelementptr %struct.FOUR_VECTOR, %struct.FOUR_VECTOR* %arrayidx9.prol.i.i, i32 0, i32 0
Lowering
        to        %basegep27 = getelementptr %struct.FOUR_VECTOR, %struct.FOUR_VECTOR* %arrayidx9.prol.i.i, i32 0, i32 0
        from      %basegep = getelementptr %struct.FOUR_VECTOR, %struct.FOUR_VECTOR* %arrayidx7.prol.i.i, i32 0, i32 0
        based on common float of size 16
[llvm] CreateGEP called
[llvm] General case
[llvm] Values: 3
[llvm] PointeeType is nullptr, replacing
[llvm] Base type: float*, ScalarPointerType: float*, ElementType: float
[llvm] Resulting type: float
[llvm] Getting GEP Return Type from Type: float
[llvm] Getting IndexedType for float
[llvm] is sized
[llvm] nullptr
lavaMD: %%/llvm/include/llvm/IR/Instructions.h: llvm::Type* llvm::checkGEPType(llvm::Type*): Assertion `Ty && "Invalid GetElementPtrInst indices for type!"' failed.

I tried setting https://github.com/cdl-saarland/rv/blob/develop/src/transform/memCopyElision.cpp#L61 as the first check instead of last, which let the pass finish.

I also checked other calls to CreateGEP. Calls with basic types (i8, float, etc..) have only 1 index, calls for complex types (Arrays, structures) have 2 or more. I suspect the issue here is that the common type gets decayed to a basic type, but still supplied with two indexes (https://github.com/cdl-saarland/rv/blob/develop/src/transform/memCopyElision.cpp#L107)

simoll commented 5 years ago

Thanks for the detailed report. I will need a test_rv test to reproduce this. Maybe you can leverage the existing memcpy test launcher.

Commaster commented 5 years ago

I'm still working on converting this test case into a test suite. For now, the module IR that RV receives: https://gist.github.com/Commaster/c8cb1928c22a2b77e358c48c01eb5163