参考经常被误解的GetElementPtr(GEP)指令 - LLVM中文网及 LLVM's getelementptr, by example
NewSrc=Builder.CreateGEP(GEPEltType, SO0, GO1, Src->getName()) 为什么?
(gdb) p SO0->dump()
i8* getelementptr inbounds ([6 x [23 x i8]], [6 x [23 x i8]]* @d, i64 0, i64 1, i64 7)
(gdb) p SO1->dump()
%0 = mul <4 x i64> %vec.ind, <i64 92, i64 92, i64 92, i64 92>(gdb) p NewSrc->dump()
i8* getelementptr inbounds ([6 x [23 x i8]], [6 x [23 x i8]]* @d, i64 0, i64 1, i64 8)
GetElementPtrInst *NewGEP = GetElementPtrInst::Create(GEPEltType, NewSrc, {SO1}) 为什么 ?
(gdb) p NewSrc->dump()
i8* getelementptr inbounds ([6 x [23 x i8]], [6 x [23 x i8]]* @d, i64 0, i64 1, i64 8)
(gdb) p SO1->dump()
%0 = mul <4 x i64> %vec.ind, <i64 92, i64 92, i64 92, i64 92>(gdb) p NewGEP->dump()
<badref> = getelementptr i8, i8* getelementptr inbounds ([6 x [23 x i8]], [6 x [23 x i8]]* @d, i64 0, i64 1, i64 8), <4 x i64> %0
(gdb) p NewGEP->setIsInBounds( true )
(gdb) p NewGEP->dump()
<badref> = getelementptr inbounds i8, i8* getelementptr inbounds ([6 x [23 x i8]], [6 x [23 x i8]]* @d, i64 0, i64 1, i64 8), <4 x i64> %0
(gdb) p NewGEP->setIsInBounds( false )
(gdb) p NewGEP->dump()
<badref> = getelementptr i8, i8* getelementptr inbounds ([6 x [23 x i8]], [6 x [23 x i8]]* @d, i64 0, i64 1, i64 8), <4 x i64> %0
2、通过 GEP->getPointerOperand() 获取GEP的base
在CodeGenPrepare::splitLargeGEPOffsets中对应offset过大的立即数进行拆分,从而保证指令选择时的合法性(拆分时对offset进行排序)
3、将GEP表达转换为i8的表达,方便后续比对,参考68882
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699
4、EmitGEPOffset可以直接将GEP的offset转成一个Value
5、在96606中表达为i8时并没有检查数据范围?
在MVEGatherScatterLowering::foldGEP中的注释说明仅处理常数就是避免溢出
MVEGatherScatterLowering::foldGEP:DL.getTypeAllocSize(GEP.getSourceElementType()) 得到整个gep obj的大小
GEP.getResultElementType() 即可获取gep最后迭代的元素类型,区别GEP.getSourceElementType()
6、 InstCombinerImpl::visitGetElementPtrInst的优化
0、对全0的gep简化的相对偏移简化,SimplifyDemandedVectorElts
1、除了结构体,所有的index类型统一为 DL.getIndexType(GEP.getPointerOperandType()->getScalarType()) Data layout chooses the right type based on supported integer types
注:clang 前端CodeGenFunction::EmitArraySubscriptExpr也可能直接生成类型转换
2、对index全常数的,Canonicalize constant GEPs to i8 type
3、gep i32 p, mul(O, C) -> gep i8, p, mul(O, C*4)