  Modern compilers, such as LLVM, are complex pieces of software. Due to their
complexity, manual testing is unlikely to suffice, yet formal verification is
difficult to scale. End-to-end fuzzing can be used, but it has difficulties in
achieving high coverage of some components of LLVM.
  In this paper, we implement IRFuzzer to investigate the effectiveness of
specialized fuzzing of the LLVM compiler backend. We focus on two approaches to
improve the fuzzer: guaranteed input validity using constrained mutations and
improved feedback quality. The mutator in IRFuzzer is capable of generating a
wide range of LLVM IR inputs, including structured control flow, vector types,
and function definitions. The system instruments coding patterns in the
compiler to monitor the execution status of instruction selection. The
instrumentation not only provides a new coverage feedback called matcher table
coverage, but also provides an architecture specific guidance to the mutator.
  We show that IRFuzzer is more effective than existing fuzzers by fuzzing on
29 mature LLVM backend targets. In the process, we reported 74 confirmed new
bugs in LLVM upstream, out of which 49 have been fixed, five have been back
ported to LLVM 15, showing that specialized fuzzing provides useful and
actionable insights to LLVM developers.
