================ @@ -4216,6 +4217,97 @@ MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(unsigned ROpc, unsigned MOpc, return CNode; } +// When the consumer of a right shift (arithmetic or logical) wouldn't notice +// the difference if the instruction was a rotate right instead (because the +// bits shifted in are truncated away), the shift can be replaced by the RORX +// instruction from BMI2. This doesn't set flags and can output to a different +// register. However, this increases code size in most cases, and doesn't leave +// the high bits in a useful state. There may be other situations where this +// transformation is profitable given those conditions, but currently the +// transformation is only made when it likely avoids spilling flags. +bool X86DAGToDAGISel::rightShiftUncloberFlags(SDNode *N) { + EVT VT = N->getValueType(0); + + // Target has to have BMI2 for RORX + if (!Subtarget->hasBMI2()) + return false; + + // Only handle scalar shifts. + if (VT.isVector()) + return false; + + unsigned OpSize; + if (VT == MVT::i64) + OpSize = 64; + else if (VT == MVT::i32) + OpSize = 32; + else if (VT == MVT::i16) + OpSize = 16; + else if (VT == MVT::i8) + return false; // i8 shift can't be truncated. + else + llvm_unreachable("Unexpected shift size"); + + unsigned TruncateSize = 0; + // This only works when the result is truncated. + for (const SDNode *User : N->uses()) { + auto name = User->getOperationName(CurDAG); ---------------- RKSimon wrote:
unused variable https://github.com/llvm/llvm-project/pull/77964 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits