diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 2dbc6785c08b9..3a04f81315e6c 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -71,50 +71,51 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { if (SrcTy == DestTy) return V; // no-op cast - // Handle casts from one vector constant to another. We know that the src - // and dest type have the same size (otherwise its an illegal cast). - if (VectorType *DestPTy = dyn_cast(DestTy)) { - if (V->isAllOnesValue()) - return Constant::getAllOnesValue(DestTy); + if (V->isAllOnesValue()) + return Constant::getAllOnesValue(DestTy); + // Handle ConstantInt -> ConstantFP + if (ConstantInt *CI = dyn_cast(V)) { // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts // This allows for other simplifications (although some of them // can only be handled by Analysis/ConstantFolding.cpp). - if (!isa(SrcTy)) - if (isa(V) || isa(V)) - return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy); - return nullptr; - } + if (isa(DestTy) && !isa(SrcTy)) + return ConstantExpr::getBitCast(ConstantVector::get(V), DestTy); - // Handle integral constant input. - if (ConstantInt *CI = dyn_cast(V)) { + // Make sure dest type is compatible with the folded fp constant. // See note below regarding the PPC_FP128 restriction. - if (DestTy->isFloatingPointTy() && !DestTy->isPPC_FP128Ty()) - return ConstantFP::get(DestTy->getContext(), - APFloat(DestTy->getFltSemantics(), - CI->getValue())); + if (!DestTy->isFPOrFPVectorTy() || DestTy->isPPC_FP128Ty() || + DestTy->getScalarSizeInBits() != SrcTy->getScalarSizeInBits()) + return nullptr; - // Otherwise, can't fold this (vector?) - return nullptr; + return ConstantFP::get( + DestTy, + APFloat(DestTy->getScalarType()->getFltSemantics(), CI->getValue())); } - // Handle ConstantFP input: FP -> Integral. + // Handle ConstantFP -> ConstantInt if (ConstantFP *FP = dyn_cast(V)) { + // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts + // This allows for other simplifications (although some of them + // can only be handled by Analysis/ConstantFolding.cpp). + if (isa(DestTy) && !isa(SrcTy)) + return ConstantExpr::getBitCast(ConstantVector::get(V), DestTy); + // PPC_FP128 is really the sum of two consecutive doubles, where the first // double is always stored first in memory, regardless of the target // endianness. The memory layout of i128, however, depends on the target // endianness, and so we can't fold this without target endianness // information. This should instead be handled by // Analysis/ConstantFolding.cpp - if (FP->getType()->isPPC_FP128Ty()) + if (SrcTy->isPPC_FP128Ty()) return nullptr; // Make sure dest type is compatible with the folded integer constant. - if (!DestTy->isIntegerTy()) + if (!DestTy->isIntOrIntVectorTy() || + DestTy->getScalarSizeInBits() != SrcTy->getScalarSizeInBits()) return nullptr; - return ConstantInt::get(FP->getContext(), - FP->getValueAPF().bitcastToAPInt()); + return ConstantInt::get(DestTy, FP->getValueAPF().bitcastToAPInt()); } return nullptr; diff --git a/llvm/test/Transforms/InstCombine/bitcast.ll b/llvm/test/Transforms/InstCombine/bitcast.ll index ce5a4635a9b0a..37d41de3e9991 100644 --- a/llvm/test/Transforms/InstCombine/bitcast.ll +++ b/llvm/test/Transforms/InstCombine/bitcast.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s +; RUN: opt < %s -passes=instcombine -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" diff --git a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll index b475b8199541d..a3ad5f0139142 100644 --- a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll +++ b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes=instsimplify -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC -; RUN: opt < %s -passes=instsimplify -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT +; RUN: opt < %s -passes=instsimplify -S | FileCheck %s +; RUN: opt < %s -passes=instsimplify -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-f64:32:64-v64:64:64-v128:128:128" define <2 x i64> @test1() { @@ -76,12 +76,8 @@ define <4 x i32> @test9(<1 x i64> %y) { } define <1 x i1> @test10() { -; CONSTVEC-LABEL: @test10( -; CONSTVEC-NEXT: [[RET:%.*]] = icmp eq <1 x i64> splat (double 0xFFFFFFFFFFFFFFFF) to i64)>, zeroinitializer -; CONSTVEC-NEXT: ret <1 x i1> [[RET]] -; -; CONSTSPLAT-LABEL: @test10( -; CONSTSPLAT-NEXT: ret <1 x i1> zeroinitializer +; CHECK-LABEL: @test10( +; CHECK-NEXT: ret <1 x i1> zeroinitializer ; %ret = icmp eq <1 x i64> to i64)>, zeroinitializer ret <1 x i1> %ret @@ -282,11 +278,8 @@ define <16 x i8> @bitcast_constexpr_16i8_8i16_u256uuu256uu() { } define <1 x i32> @bitcast_constexpr_scalar_fp_to_vector_int() { -; CONSTVEC-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int( -; CONSTVEC-NEXT: ret <1 x i32> splat (i32 1065353216) -; -; CONSTSPLAT-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int( -; CONSTSPLAT-NEXT: ret <1 x i32> bitcast (<1 x float> splat (float 1.000000e+00) to <1 x i32>) +; CHECK-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int( +; CHECK-NEXT: ret <1 x i32> splat (i32 1065353216) ; %res = bitcast float 1.0 to <1 x i32> ret <1 x i32> %res