From: Andrew Scheidecker Date: Tue, 19 Feb 2019 21:03:20 +0000 (+0000) Subject: [ConstantFold] Fix misfolding of icmp with a bitcast FP second operand. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d356001c0982bb499efd1207cec652e8711ee385;p=llvm [ConstantFold] Fix misfolding of icmp with a bitcast FP second operand. In the process of trying to eliminate the bitcast, this was producing a malformed icmp with FP operands. Differential revision: https://reviews.llvm.org/D51215 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354380 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 748a2ce475f..2c958c7dd49 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -1980,11 +1980,13 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, // 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); } diff --git a/test/Transforms/ConstProp/bitcast.ll b/test/Transforms/ConstProp/bitcast.ll index f914702f3ad..bf21fdd852f 100644 --- a/test/Transforms/ConstProp/bitcast.ll +++ b/test/Transforms/ConstProp/bitcast.ll @@ -10,19 +10,32 @@ define <1 x i64> @test1() { 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) {