diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index bb7d0c9307555b..e1e262821ef898 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2763,11 +2763,13 @@ static Instruction *foldICmpBitCast(ICmpInst &Cmp, return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); // If this is a sign-bit test of a bitcast of a casted FP value, eliminate - // the FP cast because the FP cast does not change the sign-bit. + // the FP extend/truncate because that cast does not change the sign-bit. + // This is true for all standard IEEE-754 types and the X86 80-bit type. + // The sign-bit is always the most significant bit in those types. const APInt *C; bool TrueIfSigned; - if (match(Op1, m_APInt(C)) && Bitcast->hasOneUse() && - isSignBitCheck(Pred, *C, TrueIfSigned)) { + if (!BCSrcOp->getType()->isPPC_FP128Ty() && match(Op1, m_APInt(C)) && + Bitcast->hasOneUse() && isSignBitCheck(Pred, *C, TrueIfSigned)) { if (match(BCSrcOp, m_FPExt(m_Value(X))) || match(BCSrcOp, m_FPTrunc(m_Value(X)))) { // (bitcast (fpext/fptrunc X)) to iX) < 0 --> (bitcast X to iY) < 0 diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 2da5c696d04672..96673eb9e45119 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -3700,8 +3700,9 @@ define i1 @signbit_bitcast_fpext_extra_use(float %x, i64* %p) { define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) { ; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128( -; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 -; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[TMP1]], 0 +; CHECK-NEXT: [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128 +; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128 +; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 0 ; CHECK-NEXT: ret i1 [[S4]] ; %s2 = fpext float %x to ppc_fp128