mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
InstCombine: Fold bitcast of vector to FP scalar
llvm-svn: 288978
This commit is contained in:
parent
98f9dd59fb
commit
61527cb46b
@ -88,7 +88,7 @@ static Constant *foldConstVectorToAPInt(APInt &Result, Type *DestTy,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constant fold bitcast, symbolically evaluating it with DataLayout.
|
/// Constant fold bitcast, symbolically evaluating it with DataLayout.
|
||||||
/// This always returns a non-null constant, but it may be a
|
/// This always returns a non-null constant, but it may be a
|
||||||
/// ConstantExpr if unfoldable.
|
/// ConstantExpr if unfoldable.
|
||||||
Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
|
Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
|
||||||
@ -99,31 +99,33 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
|
|||||||
!DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types!
|
!DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types!
|
||||||
return Constant::getAllOnesValue(DestTy);
|
return Constant::getAllOnesValue(DestTy);
|
||||||
|
|
||||||
// Handle a vector->integer cast.
|
if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
|
||||||
if (auto *IT = dyn_cast<IntegerType>(DestTy)) {
|
// Handle a vector->scalar integer/fp cast.
|
||||||
auto *VTy = dyn_cast<VectorType>(C->getType());
|
if (isa<IntegerType>(DestTy) || DestTy->isFloatingPointTy()) {
|
||||||
if (!VTy)
|
unsigned NumSrcElts = VTy->getNumElements();
|
||||||
return ConstantExpr::getBitCast(C, DestTy);
|
Type *SrcEltTy = VTy->getElementType();
|
||||||
|
|
||||||
unsigned NumSrcElts = VTy->getNumElements();
|
// If the vector is a vector of floating point, convert it to vector of int
|
||||||
Type *SrcEltTy = VTy->getElementType();
|
// to simplify things.
|
||||||
|
if (SrcEltTy->isFloatingPointTy()) {
|
||||||
|
unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
|
||||||
|
Type *SrcIVTy =
|
||||||
|
VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElts);
|
||||||
|
// Ask IR to do the conversion now that #elts line up.
|
||||||
|
C = ConstantExpr::getBitCast(C, SrcIVTy);
|
||||||
|
}
|
||||||
|
|
||||||
// If the vector is a vector of floating point, convert it to vector of int
|
APInt Result(DL.getTypeSizeInBits(DestTy), 0);
|
||||||
// to simplify things.
|
if (Constant *CE = foldConstVectorToAPInt(Result, DestTy, C,
|
||||||
if (SrcEltTy->isFloatingPointTy()) {
|
SrcEltTy, NumSrcElts, DL))
|
||||||
unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
|
return CE;
|
||||||
Type *SrcIVTy =
|
|
||||||
VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElts);
|
if (isa<IntegerType>(DestTy))
|
||||||
// Ask IR to do the conversion now that #elts line up.
|
return ConstantInt::get(DestTy, Result);
|
||||||
C = ConstantExpr::getBitCast(C, SrcIVTy);
|
|
||||||
|
APFloat FP(DestTy->getFltSemantics(), Result);
|
||||||
|
return ConstantFP::get(DestTy->getContext(), FP);
|
||||||
}
|
}
|
||||||
|
|
||||||
APInt Result(IT->getBitWidth(), 0);
|
|
||||||
if (Constant *CE = foldConstVectorToAPInt(Result, DestTy, C,
|
|
||||||
SrcEltTy, NumSrcElts, DL))
|
|
||||||
return CE;
|
|
||||||
|
|
||||||
return ConstantInt::get(IT, Result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code below only handles casts to vectors currently.
|
// The code below only handles casts to vectors currently.
|
||||||
|
@ -449,3 +449,67 @@ define i8 @test8() {
|
|||||||
%res = bitcast <8 x i1> <i1 true, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true> to i8
|
%res = bitcast <8 x i1> <i1 true, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true> to i8
|
||||||
ret i8 %res
|
ret i8 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@g = internal unnamed_addr global i32 undef
|
||||||
|
|
||||||
|
; CHECK-LABEL: @constant_fold_vector_to_double(
|
||||||
|
; CHECK: store volatile double 1.000000e+00,
|
||||||
|
; CHECK: store volatile double 1.000000e+00,
|
||||||
|
; CHECK: store volatile double 1.000000e+00,
|
||||||
|
; CHECK: store volatile double 1.000000e+00,
|
||||||
|
|
||||||
|
; CHECK: store volatile double 0xFFFFFFFFFFFFFFFF,
|
||||||
|
; CHECK: store volatile double 0x162E000004D2,
|
||||||
|
|
||||||
|
; CHECK: store volatile double bitcast (<2 x i32> <i32 1234, i32 ptrtoint (i32* @g to i32)> to double),
|
||||||
|
; CHECK: store volatile double 0x400000003F800000,
|
||||||
|
|
||||||
|
; CHECK: store volatile double 0.000000e+00,
|
||||||
|
; CHECK: store volatile double 0.000000e+00,
|
||||||
|
; CHECK: store volatile double 0.000000e+00,
|
||||||
|
; CHECK: store volatile double 0.000000e+00,
|
||||||
|
; CHECK: store volatile double 0.000000e+00,
|
||||||
|
; CHECK: store volatile double 0.000000e+00,
|
||||||
|
define void @constant_fold_vector_to_double() {
|
||||||
|
store volatile double bitcast (<1 x i64> <i64 4607182418800017408> to double), double* undef
|
||||||
|
store volatile double bitcast (<2 x i32> <i32 0, i32 1072693248> to double), double* undef
|
||||||
|
store volatile double bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 16368> to double), double* undef
|
||||||
|
store volatile double bitcast (<8 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 240, i8 63> to double), double* undef
|
||||||
|
|
||||||
|
store volatile double bitcast (<2 x i32> <i32 -1, i32 -1> to double), double* undef
|
||||||
|
store volatile double bitcast (<2 x i32> <i32 1234, i32 5678> to double), double* undef
|
||||||
|
|
||||||
|
store volatile double bitcast (<2 x i32> <i32 1234, i32 ptrtoint (i32* @g to i32)> to double), double* undef
|
||||||
|
store volatile double bitcast (<2 x float> <float 1.0, float 2.0> to double), double* undef
|
||||||
|
|
||||||
|
store volatile double bitcast (<2 x i32> zeroinitializer to double), double* undef
|
||||||
|
store volatile double bitcast (<4 x i16> zeroinitializer to double), double* undef
|
||||||
|
store volatile double bitcast (<8 x i8> zeroinitializer to double), double* undef
|
||||||
|
store volatile double bitcast (<16 x i4> zeroinitializer to double), double* undef
|
||||||
|
store volatile double bitcast (<32 x i2> zeroinitializer to double), double* undef
|
||||||
|
store volatile double bitcast (<64 x i1> zeroinitializer to double), double* undef
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: @constant_fold_vector_to_float(
|
||||||
|
; CHECK: store volatile float 1.000000e+00,
|
||||||
|
; CHECK: store volatile float 1.000000e+00,
|
||||||
|
; CHECK: store volatile float 1.000000e+00,
|
||||||
|
; CHECK: store volatile float 1.000000e+00,
|
||||||
|
define void @constant_fold_vector_to_float() {
|
||||||
|
store volatile float bitcast (<1 x i32> <i32 1065353216> to float), float* undef
|
||||||
|
store volatile float bitcast (<2 x i16> <i16 0, i16 16256> to float), float* undef
|
||||||
|
store volatile float bitcast (<4 x i8> <i8 0, i8 0, i8 128, i8 63> to float), float* undef
|
||||||
|
store volatile float bitcast (<32 x i1> <i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 0, i1 0> to float), float* undef
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: @constant_fold_vector_to_half(
|
||||||
|
; CHECK: store volatile half 0xH4000,
|
||||||
|
; CHECK: store volatile half 0xH4000,
|
||||||
|
define void @constant_fold_vector_to_half() {
|
||||||
|
store volatile half bitcast (<2 x i8> <i8 0, i8 64> to half), half* undef
|
||||||
|
store volatile half bitcast (<4 x i4> <i4 0, i4 0, i4 0, i4 4> to half), half* undef
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user