// we have different element types.
SmallVector<VectorType *, 4> CandidateTys;
Type *CommonEltTy = nullptr;
+ VectorType *CommonVecPtrTy = nullptr;
+ bool HaveVecPtrTy = false;
bool HaveCommonEltTy = true;
+ bool HaveCommonVecPtrTy = true;
auto CheckCandidateType = [&](Type *Ty) {
if (auto *VTy = dyn_cast<VectorType>(Ty)) {
// Return if bitcast to vectors is different for total size in bits.
}
}
CandidateTys.push_back(VTy);
+ Type *EltTy = VTy->getElementType();
+
if (!CommonEltTy)
- CommonEltTy = VTy->getElementType();
- else if (CommonEltTy != VTy->getElementType())
+ CommonEltTy = EltTy;
+ else if (CommonEltTy != EltTy)
HaveCommonEltTy = false;
+
+ if (EltTy->isPointerTy()) {
+ HaveVecPtrTy = true;
+ if (!CommonVecPtrTy)
+ CommonVecPtrTy = VTy;
+ else if (CommonVecPtrTy != VTy)
+ HaveCommonVecPtrTy = false;
+ }
}
};
// Consider any loads or stores that are the exact size of the slice.
if (CandidateTys.empty())
return nullptr;
- // Remove non-integer vector types if we had multiple common element types.
- // FIXME: It'd be nice to replace them with integer vector types, but we can't
- // do that until all the backends are known to produce good code for all
- // integer vector types.
- if (!HaveCommonEltTy) {
+ // Pointer-ness is sticky, if we had a vector-of-pointers candidate type,
+ // then we should choose it, not some other alternative.
+ // But, we can't perform a no-op pointer address space change via bitcast,
+ // so if we didn't have a common pointer element type, bail.
+ if (HaveVecPtrTy && !HaveCommonVecPtrTy)
+ return nullptr;
+
+ // Try to pick the "best" element type out of the choices.
+ if (!HaveCommonEltTy && HaveVecPtrTy) {
+ // If there was a pointer element type, there's really only one choice.
+ CandidateTys.clear();
+ CandidateTys.push_back(CommonVecPtrTy);
+ } else if (!HaveCommonEltTy && !HaveVecPtrTy) {
+ // Remove non-integer vector types if we had multiple common element types.
+ // FIXME: It'd be nice to replace them with integer vector types, but we
+ // can't do that until all the backends are known to produce good code for
+ // all integer vector types.
llvm::erase_if(CandidateTys, [](VectorType *VTy) {
return !VTy->getElementType()->isIntegerTy();
});
define <2 x ptr> @vector_inttoptrbitcast_vector({<16 x i8>, <16 x i8>} %x) {
; CHECK-LABEL: @vector_inttoptrbitcast_vector(
; CHECK-NEXT: [[X_FCA_0_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[X:%.*]], 0
-; CHECK-NEXT: [[X_FCA_1_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[X_FCA_0_EXTRACT]] to <2 x i64>
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr <2 x i64> [[TMP1]] to <2 x ptr>
+; CHECK-NEXT: [[X_FCA_1_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[X]], 1
; CHECK-NEXT: ret <2 x ptr> [[TMP2]]
;
%a = alloca {<16 x i8>, <16 x i8>}
define <16 x i8> @vector_ptrtointbitcast_vector({<2 x ptr>, <2 x ptr>} %x) {
; CHECK-LABEL: @vector_ptrtointbitcast_vector(
; CHECK-NEXT: [[X_FCA_0_EXTRACT:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[X:%.*]], 0
+; CHECK-NEXT: [[X_FCA_1_EXTRACT:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr> [[X_FCA_0_EXTRACT]] to <2 x i64>
; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
-; CHECK-NEXT: [[X_FCA_1_EXTRACT:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[X]], 1
; CHECK-NEXT: ret <16 x i8> [[TMP2]]
;
%a = alloca {<2 x ptr>, <2 x ptr>}