diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 3a04f81315e6c..b577f69eeaba0 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -198,9 +198,9 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, if (ConstantFP *FPC = dyn_cast(V)) { bool ignored; APFloat Val = FPC->getValueAPF(); - Val.convert(DestTy->getFltSemantics(), APFloat::rmNearestTiesToEven, - &ignored); - return ConstantFP::get(V->getContext(), Val); + Val.convert(DestTy->getScalarType()->getFltSemantics(), + APFloat::rmNearestTiesToEven, &ignored); + return ConstantFP::get(DestTy, Val); } return nullptr; // Can't fold. case Instruction::FPToUI: @@ -208,26 +208,25 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, if (ConstantFP *FPC = dyn_cast(V)) { const APFloat &V = FPC->getValueAPF(); bool ignored; - uint32_t DestBitWidth = cast(DestTy)->getBitWidth(); - APSInt IntVal(DestBitWidth, opc == Instruction::FPToUI); + APSInt IntVal(DestTy->getScalarSizeInBits(), opc == Instruction::FPToUI); if (APFloat::opInvalidOp == V.convertToInteger(IntVal, APFloat::rmTowardZero, &ignored)) { // Undefined behavior invoked - the destination type can't represent // the input constant. return PoisonValue::get(DestTy); } - return ConstantInt::get(FPC->getContext(), IntVal); + return ConstantInt::get(DestTy, IntVal); } return nullptr; // Can't fold. case Instruction::UIToFP: case Instruction::SIToFP: if (ConstantInt *CI = dyn_cast(V)) { const APInt &api = CI->getValue(); - APFloat apf(DestTy->getFltSemantics(), - APInt::getZero(DestTy->getPrimitiveSizeInBits())); + APFloat apf(DestTy->getScalarType()->getFltSemantics(), + APInt::getZero(DestTy->getScalarSizeInBits())); apf.convertFromAPInt(api, opc==Instruction::SIToFP, APFloat::rmNearestTiesToEven); - return ConstantFP::get(V->getContext(), apf); + return ConstantFP::get(DestTy, apf); } return nullptr; case Instruction::ZExt: @@ -573,7 +572,7 @@ Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) { default: break; case Instruction::FNeg: - return ConstantFP::get(C->getContext(), neg(CV)); + return ConstantFP::get(C->getType(), neg(CV)); } } else if (auto *VTy = dyn_cast(C->getType())) { // Fast path for splatted constants. @@ -857,19 +856,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, break; case Instruction::FAdd: (void)C3V.add(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C1->getContext(), C3V); + return ConstantFP::get(C1->getType(), C3V); case Instruction::FSub: (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C1->getContext(), C3V); + return ConstantFP::get(C1->getType(), C3V); case Instruction::FMul: (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C1->getContext(), C3V); + return ConstantFP::get(C1->getType(), C3V); case Instruction::FDiv: (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C1->getContext(), C3V); + return ConstantFP::get(C1->getType(), C3V); case Instruction::FRem: (void)C3V.mod(C2V); - return ConstantFP::get(C1->getContext(), C3V); + return ConstantFP::get(C1->getType(), C3V); } } } diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 95832ed0b8951..949c23609c9d0 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -358,6 +358,9 @@ bool Constant::containsUndefElement() const { } bool Constant::containsConstantExpression() const { + if (isa(this) || isa(this)) + return false; + if (auto *VTy = dyn_cast(getType())) { for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) if (isa(getAggregateElement(i))) diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll index a81259b147fb7..478d437847127 100644 --- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll +++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.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 ; (X < C1) ? C1 : MIN(X, C2) define float @clamp_float_fast_ordered_strict_maxmin(float %x) { diff --git a/llvm/test/Transforms/InstCombine/fabs-fneg-fold.ll b/llvm/test/Transforms/InstCombine/fabs-fneg-fold.ll index dd8d0aed3210e..b77d6b51f9220 100644 --- a/llvm/test/Transforms/InstCombine/fabs-fneg-fold.ll +++ b/llvm/test/Transforms/InstCombine/fabs-fneg-fold.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S -passes=instcombine %s | FileCheck %s +; RUN: opt -S -passes=instcombine -use-constant-fp-for-fixed-length-splat %s | FileCheck %s define float @fabs_fneg_basic(float %x) { ; CHECK-LABEL: define float @fabs_fneg_basic( diff --git a/llvm/test/Transforms/InstCombine/fadd.ll b/llvm/test/Transforms/InstCombine/fadd.ll index 36c387969d05d..094137b7f3ddf 100644 --- a/llvm/test/Transforms/InstCombine/fadd.ll +++ b/llvm/test/Transforms/InstCombine/fadd.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 -S | FileCheck %s declare void @use(float) declare void @use_vec(<2 x float>) diff --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll index ad187e22014e4..54b0bf8c50ac7 100644 --- a/llvm/test/Transforms/InstCombine/fdiv.ll +++ b/llvm/test/Transforms/InstCombine/fdiv.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 < %s | FileCheck %s declare float @llvm.fabs.f32(float) nounwind readnone declare float @llvm.pow.f32(float, float) nounwind readnone diff --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll index fde0b8ab461a9..cd4a8e36c6e23 100644 --- a/llvm/test/Transforms/InstCombine/fmul.ll +++ b/llvm/test/Transforms/InstCombine/fmul.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 < %s | FileCheck %s ; (-0.0 - X) * C => X * -C define float @neg_constant(float %x) { diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll index 549291f2c4f0d..755beff9bf77a 100644 --- a/llvm/test/Transforms/InstCombine/fneg.ll +++ b/llvm/test/Transforms/InstCombine/fneg.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 -S | FileCheck %s declare float @llvm.ldexp.f32.i32(float, i32) declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>)