From b8456460cbf3134ad196584a3049ac9b1109628b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 20 Sep 2006 04:44:59 +0000 Subject: [PATCH] We went through all that trouble to compute whether it was safe to transform this comparison, but never checked it. Whoops, no wonder we miscompiled 177.mesa! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30511 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 58d4b8ff139..8f6d5348e67 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -5713,12 +5713,51 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { return new CastInst(NotCond, SI.getType()); } - // If one of the constants is zero (we know they can't both be) and we - // have a setcc instruction with zero, and we have an 'and' with the - // non-constant value, eliminate this whole mess. This corresponds to - // cases like this: ((X & 27) ? 27 : 0) - if (TrueValC->isNullValue() || FalseValC->isNullValue()) - if (SetCondInst *IC = dyn_cast(SI.getCondition())) + if (SetCondInst *IC = dyn_cast(SI.getCondition())) { + + // (x sra x, 31 + // (x >u 2147483647) ? -1 : 0 -> sra x, 31 + if (TrueValC->isAllOnesValue() && FalseValC->isNullValue()) + if (ConstantInt *CmpCst = dyn_cast(IC->getOperand(1))) { + bool CanXForm = false; + if (CmpCst->getType()->isSigned()) + CanXForm = CmpCst->isNullValue() && + IC->getOpcode() == Instruction::SetLT; + else { + unsigned Bits = CmpCst->getType()->getPrimitiveSizeInBits(); + CanXForm = (CmpCst->getRawValue() == ~0ULL >> (64-Bits+1)) && + IC->getOpcode() == Instruction::SetGT; + } + + if (CanXForm) { + // The comparison constant and the result are not neccessarily the + // same width. In any case, the first step to do is make sure + // that X is signed. + Value *X = IC->getOperand(0); + if (!X->getType()->isSigned()) + X = InsertCastBefore(X, X->getType()->getSignedVersion(), SI); + + // Now that X is signed, we have to make the all ones value. Do + // this by inserting a new SRA. + unsigned Bits = X->getType()->getPrimitiveSizeInBits(); + Constant *ShAmt = ConstantUInt::get(Type::UByteTy, Bits-1); + Instruction *SRA = new ShiftInst(Instruction::Shr, X, + ShAmt, "ones"); + InsertNewInstBefore(SRA, SI); + + // Finally, convert to the type of the select RHS. If this is + // smaller than the compare value, it will truncate the ones to + // fit. If it is larger, it will sext the ones to fit. + return new CastInst(SRA, SI.getType()); + } + } + + + // If one of the constants is zero (we know they can't both be) and we + // have a setcc instruction with zero, and we have an 'and' with the + // non-constant value, eliminate this whole mess. This corresponds to + // cases like this: ((X & 27) ? 27 : 0) + if (TrueValC->isNullValue() || FalseValC->isNullValue()) if (IC->isEquality() && isa(IC->getOperand(1)) && cast(IC->getOperand(1))->isNullValue()) if (Instruction *ICA = dyn_cast(IC->getOperand(0))) @@ -5738,6 +5777,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { Instruction::Xor, V, ICA->getOperand(1)), SI); return ReplaceInstUsesWith(SI, V); } + } } // See if we are selecting two values based on a comparison of the two values. -- 2.34.1