@@ -111,6 +111,31 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
111
111
if (SrcTy == DestTy)
112
112
return V; // no-op cast
113
113
114
+ #ifndef INTEL_SYCL_OPAQUEPOINTER_READY
115
+ // Check to see if we are casting a pointer to an aggregate to a pointer to
116
+ // the first element. If so, return the appropriate GEP instruction.
117
+ if (PointerType *PTy = dyn_cast<PointerType>(V->getType ()))
118
+ if (PointerType *DPTy = dyn_cast<PointerType>(DestTy))
119
+ if (PTy->getAddressSpace () == DPTy->getAddressSpace () &&
120
+ !PTy->isOpaque () && !DPTy->isOpaque () &&
121
+ PTy->getNonOpaquePointerElementType ()->isSized ()) {
122
+ SmallVector<Value*, 8 > IdxList;
123
+ Value *Zero =
124
+ Constant::getNullValue (Type::getInt32Ty (DPTy->getContext ()));
125
+ IdxList.push_back (Zero);
126
+ Type *ElTy = PTy->getNonOpaquePointerElementType ();
127
+ while (ElTy && ElTy != DPTy->getNonOpaquePointerElementType ()) {
128
+ ElTy = GetElementPtrInst::getTypeAtIndex (ElTy, (uint64_t )0 );
129
+ IdxList.push_back (Zero);
130
+ }
131
+
132
+ if (ElTy == DPTy->getNonOpaquePointerElementType ())
133
+ // This GEP is inbounds because all indices are zero.
134
+ return ConstantExpr::getInBoundsGetElementPtr (
135
+ PTy->getNonOpaquePointerElementType (), V, IdxList);
136
+ }
137
+ #endif // INTEL_SYCL_OPAQUEPOINTER_READY
138
+
114
139
// Handle casts from one vector constant to another. We know that the src
115
140
// and dest type have the same size (otherwise its an illegal cast).
116
141
if (VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
@@ -2010,6 +2035,12 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
2010
2035
return InBounds ? PoisonValue::get (GEPTy) : UndefValue::get (GEPTy);
2011
2036
2012
2037
auto IsNoOp = [&]() {
2038
+ #ifndef INTEL_SYCL_OPAQUEPOINTER_READY
2039
+ // For non-opaque pointers having multiple indices will change the result
2040
+ // type of the GEP.
2041
+ if (!C->getType ()->getScalarType ()->isOpaquePointerTy () && Idxs.size () != 1 )
2042
+ return false ;
2043
+ #endif // INTEL_SYCL_OPAQUEPOINTER_READY
2013
2044
// Avoid losing inrange information.
2014
2045
if (InRangeIndex)
2015
2046
return false ;
@@ -2058,10 +2089,41 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
2058
2089
}
2059
2090
}
2060
2091
2061
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
2092
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
2062
2093
if (auto *GEP = dyn_cast<GEPOperator>(CE))
2063
2094
if (Constant *C = foldGEPOfGEP (GEP, PointeeTy, InBounds, Idxs))
2064
2095
return C;
2096
+ #ifndef INTEL_SYCL_OPAQUEPOINTER_READY
2097
+ // Attempt to fold casts to the same type away. For example, folding:
2098
+ //
2099
+ // i32* getelementptr ([2 x i32]* bitcast ([3 x i32]* %X to [2 x i32]*),
2100
+ // i64 0, i64 0)
2101
+ // into:
2102
+ //
2103
+ // i32* getelementptr ([3 x i32]* %X, i64 0, i64 0)
2104
+ //
2105
+ // Don't fold if the cast is changing address spaces.
2106
+ Constant *Idx0 = cast<Constant>(Idxs[0 ]);
2107
+ if (CE->isCast () && Idxs.size () > 1 && Idx0->isNullValue ()) {
2108
+ PointerType *SrcPtrTy =
2109
+ dyn_cast<PointerType>(CE->getOperand (0 )->getType ());
2110
+ PointerType *DstPtrTy = dyn_cast<PointerType>(CE->getType ());
2111
+ if (SrcPtrTy && DstPtrTy && !SrcPtrTy->isOpaque () &&
2112
+ !DstPtrTy->isOpaque ()) {
2113
+ ArrayType *SrcArrayTy =
2114
+ dyn_cast<ArrayType>(SrcPtrTy->getNonOpaquePointerElementType ());
2115
+ ArrayType *DstArrayTy =
2116
+ dyn_cast<ArrayType>(DstPtrTy->getNonOpaquePointerElementType ());
2117
+ if (SrcArrayTy && DstArrayTy
2118
+ && SrcArrayTy->getElementType () == DstArrayTy->getElementType ()
2119
+ && SrcPtrTy->getAddressSpace () == DstPtrTy->getAddressSpace ())
2120
+ return ConstantExpr::getGetElementPtr (SrcArrayTy,
2121
+ (Constant *)CE->getOperand (0 ),
2122
+ Idxs, InBounds, InRangeIndex);
2123
+ }
2124
+ }
2125
+ #endif // INTEL_SYCL_OPAQUEPOINTER_READY
2126
+ }
2065
2127
2066
2128
// Check to see if any array indices are not within the corresponding
2067
2129
// notional array or vector bounds. If so, try to determine if they can be
0 commit comments