//===- X86FixupSetCC.cpp - fix zero-extension of setcc patterns -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines a pass that fixes zero-extension of setcc patterns. // X86 setcc instructions are modeled to have no input arguments, and a single // GR8 output argument. This is consistent with other similar instructions // (e.g. movb), but means it is impossible to directly generate a setcc into // the lower GR8 of a specified GR32. // This means that ISel must select (zext (setcc)) into something like // seta %al; movzbl %al, %eax. // Unfortunately, this can cause a stall due to the partial register write // performed by the setcc. Instead, we can use: // xor %eax, %eax; seta %al // This both avoids the stall, and encodes shorter. // // Furthurmore, we can use: // setzua %al // if feature zero-upper is available. It's faster than the xor+setcc sequence. // When r16-r31 is used, it even encodes shorter. //===----------------------------------------------------------------------===// #include "X86.h" #include "X86InstrInfo.h" #include "X86Subtarget.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" usingnamespacellvm; #define DEBUG_TYPE … STATISTIC(NumSubstZexts, "Number of setcc + zext pairs substituted"); namespace { class X86FixupSetCCPass : public MachineFunctionPass { … }; } // end anonymous namespace char X86FixupSetCCPass::ID = …; INITIALIZE_PASS(…) FunctionPass *llvm::createX86FixupSetCC() { … } bool X86FixupSetCCPass::runOnMachineFunction(MachineFunction &MF) { … }