Index: llvm/trunk/lib/IR/ConstantFold.cpp =================================================================== --- llvm/trunk/lib/IR/ConstantFold.cpp +++ llvm/trunk/lib/IR/ConstantFold.cpp @@ -1980,11 +1980,13 @@ // If the right hand side is a bitcast, try using its inverse to simplify // it by moving it to the left hand side. We can't do this if it would turn - // a vector compare into a scalar compare or visa versa. + // a vector compare into a scalar compare or visa versa, or if it would turn + // the operands into FP values. if (ConstantExpr *CE2 = dyn_cast(C2)) { Constant *CE2Op0 = CE2->getOperand(0); if (CE2->getOpcode() == Instruction::BitCast && - CE2->getType()->isVectorTy() == CE2Op0->getType()->isVectorTy()) { + CE2->getType()->isVectorTy() == CE2Op0->getType()->isVectorTy() && + !CE2Op0->getType()->isFPOrFPVectorTy()) { Constant *Inverse = ConstantExpr::getBitCast(C1, CE2Op0->getType()); return ConstantExpr::getICmp(pred, Inverse, CE2Op0); } Index: llvm/trunk/test/Transforms/ConstProp/bitcast.ll =================================================================== --- llvm/trunk/test/Transforms/ConstProp/bitcast.ll +++ llvm/trunk/test/Transforms/ConstProp/bitcast.ll @@ -10,19 +10,32 @@ ret <1 x i64> %A } -; FIXME: Don't try to propagate an FP source operand to an icmp. +; Ensure that a FP source operand isn't propagated to an icmp. @a = external global i16, align 1 @b = external global i16, align 1 define i1 @bad_icmp_constexpr_bitcast() { ; CHECK-LABEL: @bad_icmp_constexpr_bitcast( -; CHECK-NEXT: ret i1 icmp eq (float bitcast (i32 ptrtoint (i16* @a to i32) to float), float fadd (float bitcast (i32 ptrtoint (i16* @b to i32) to float), float 2.000000e+00)) +; CHECK-NEXT: ret i1 icmp eq (i32 ptrtoint (i16* @a to i32), i32 bitcast (float fadd (float bitcast (i32 ptrtoint (i16* @b to i32) to float), float 2.000000e+00) to i32)) ; %cmp = icmp eq i32 ptrtoint (i16* @a to i32), bitcast (float fadd (float bitcast (i32 ptrtoint (i16* @b to i32) to float), float 2.0) to i32) ret i1 %cmp } +; Ensure that an integer source operand isn't propagated to a fcmp. + +@c = external global i16, align 1 +@d = external global i16, align 1 + +define i1 @bad_fcmp_constexpr_bitcast() { +; CHECK-LABEL: @bad_fcmp_constexpr_bitcast( +; CHECK-NEXT: ret i1 fcmp oeq (float bitcast (i32 ptrtoint (i16* @c to i32) to float), float bitcast (i32 add (i32 ptrtoint (i16* @d to i32), i32 2) to float)) +; + %cmp = fcmp oeq float bitcast (i32 ptrtoint (i16* @c to i32) to float), bitcast (i32 add (i32 ptrtoint (i16* @d to i32), i32 2) to float) + ret i1 %cmp +} + ; FIXME: If the bitcasts result in a NaN FP value, then "ordered and equal" would be false. define i1 @fcmp_constexpr_oeq(float %conv) {