Theory test — Chapter 12¶
61 questions; you pass at 80 %. This page shows the questions only: take the test in the terminal, where every answer is graded and explained.
./course quiz 12 # interactive
./course quiz template 12 -o answers/ch12.yaml # or fill in a file ...
./course quiz grade 12 # ... and grade it
pm-cache-trace · mapping · 1 pt · 01-pass-manager-architecturesA function pipeline runs on one function, starting with an empty cache, under LLVM 23's rules
(Lesson 12.1: DT, PDT, LI are kept by the CFG set; AC and TLI are never invalidated; BasicAA and AA
are stateless and fall only with a dependency; SE depends on AC, DT, LI; MSSA on AA, DT; computing
LI requests DT, SE requests TLI, AC, DT, LI, BasicAA requests AC, DT, TLI, AA requests BasicAA,
MSSA requests AA, DT).
- P1 requests {SE}, returns preserved = {CFG}
- P2 requests {AA}, returns all
- P3 requests {LI}, returns none
- P4 requests {MSSA}, returns preserved = {CFG}
For each pass, which analyses are computed during it? (Write {} for none.)
P1, P2, P3, P4pm-cascade · set · 1 pt · 01-pass-manager-architecturesThe cache holds SE, TLI, AC, DT, LI, MSSA, AA and BasicAA for a function. The pass
invalidate<domtree> runs; it reports "everything preserved except DominatorTreeAnalysis". Which
analyses are invalidated? (LLVM 23's invalidate methods, Lesson 12.1.)
pm-legacy-vs-new · multi · 1 pt · 01-pass-manager-architecturesWhich statements about pass managers are true?
- The legacy LLVM pass manager learns what a pass preserved from the value the pass returns after running.
- The new LLVM pass manager computes analyses lazily, when a pass asks for them, and caches the results.
- GCC's pass manager tracks IR properties such as PROP_ssa and runs TODO actions such as TODO_update_ssa after passes.
- MLIR anchors each nested pipeline on an operation type, and anchored operations must be IsolatedFromAbove.
- In LLVM 23, opt still runs the optimization pipeline with the legacy pass manager when given -enable-new-pm=0.
pm-optional-required · single · 1 pt · 01-pass-manager-architecturesA function has the optnone attribute and opt runs -opt-bisect-limit=0 on
function(pebble-strength,print<pebble-stats>), where pebble-strength derives from
OptionalPassInfoMixin and the printer from RequiredPassInfoMixin. What runs on that function?
- Both passes: optnone only affects code generation.
- Only the printer: optional passes are skipped by the optnone and opt-bisect instrumentation, required ones never.
- Neither: -opt-bisect-limit=0 skips every pass.
- Only pebble-strength: printers are skipped under optnone.
pm-legacy-declare · single · 1 pt · 01-pass-manager-architecturesUnder LLVM's legacy pass manager, a function pass changes the CFG on 1 function in 100 and leaves the other
99 untouched. What must it declare in getAnalysisUsage, and what does that cost?
- setPreservesCFG(); nothing is recomputed.
- Nothing about the CFG (it cannot promise to preserve it), so every CFG analysis is freed and recomputed after it on all 100 functions.
- It returns PreservedAnalyses::none() for the one function only.
- The legacy manager detects the change and recomputes on that function only.
pm-gcc-properties · single · 1 pt · 01-pass-manager-architecturesA GCC pass has properties_required = PROP_cfg | PROP_ssa, properties_provided = 0,
properties_destroyed = PROP_ssa. Before it runs, the property set is {PROP_cfg, PROP_ssa, PROP_loops}.
What is it afterwards (Algorithm 12.1.13)?
- {PROP_cfg, PROP_loops}
- {PROP_cfg, PROP_ssa, PROP_loops}
- {PROP_loops}
- {PROP_cfg}
pm-mlir-anchor · single · 1 pt · 01-pass-manager-architecturesWhy may MLIR run a func.func pipeline on different functions in parallel?
- Because functions never call each other.
- Because func.func is IsolatedFromAbove and passes may modify only the operation they run on, so the jobs touch disjoint IR.
- Because MLIR copies the whole module for each thread.
- Because the pass manager locks the module for every pass.
pm-cgscc-order · sequence · 1 pt · 01-pass-manager-architecturesA module has functions main, f, g, h with calls main → f, f → g, g → h (no recursion). In which order does
cgscc(inline) visit the SCCs? Write the function names.
llvm-where-optnone · text · 1 pt · 01-pass-manager-architecturesIn LLVM 23.1.2, open llvm/lib/Passes/StandardInstrumentations.cpp and find how optnone functions are
skipped. Which PassInstrumentationCallbacks registration function does OptNoneInstrumentation::registerCallbacks
call? (the method name)
llvm-where-invalidate-scev · set · 1 pt · 01-pass-manager-architecturesOpen llvm/lib/Analysis/ScalarEvolution.cpp at llvmorg-23.1.2 and read ScalarEvolution::invalidate.
Which analyses does it ask the Invalidator about? Answer with AC (AssumptionAnalysis), DT
(DominatorTreeAnalysis), LI (LoopAnalysis), TLI (TargetLibraryAnalysis), AA (AAManager).
pipe-ep-count · number · 1 pt · 02-pipelines-and-extension-pointsWith LLVM 23.1.2, opt -passes='default<O2>' -passes-ep-peephole='instnamer' -print-pipeline-passes
shows how many occurrences of instnamer (the Peephole extension point) per function pipeline?
pipe-o2-not-o1 · set · 1 pt · 02-pipelines-and-extension-pointsWhich of these passes appear in LLVM 23's default<O2> pipeline but not in default<O1>:
gvn, instcombine, sroa, slp-vectorizer, dse, licm?
pipe-os · single · 1 pt · 02-pipelines-and-extension-pointsWhat does -Os mean for LLVM 23?
- A separate pipeline
default<Os>with size-oriented passes. - The O2 pipeline, with the optsize attribute on functions;
opt -passes='default<Os>'is an error. - The O1 pipeline without inlining.
- The O3 pipeline with unrolling disabled.
plugin-ep-parse · single · 1 pt · 02-pipelines-and-extension-pointsWhy does opt -load-pass-plugin=PebblePasses.so -passes='default<O2>' -passes-ep-peephole=pebble-strength
print "unknown function pass 'pebble-strength'"?
- Plugin passes cannot run inside default pipelines.
- opt parses the -passes-ep-* texts in registerEPCallbacks before the plugin's parsing callbacks are registered, so the name is unknown at that time.
- The Peephole extension point accepts only loop passes.
- pebble-strength is a module pass.
phase-commute · number · 1 pt · 02-pipelines-and-extension-pointsLesson 12.2 §3 runs all 3! = 6 orders of {mem2reg, early-cse, pebble-strength} on
int f(int a, int b){int x=a*b; int y=a*b; return (x+y)*8;} (clang -O0 IR). In how many of the six
orders does the result have the minimum of 4 instructions?
phase-search-bound · number · 1 pt · 02-pipelines-and-extension-pointsAlgorithm 12.2.7 explores pass sequences of length at most L = 3 over |Σ| = 3 passes. In the worst case,
when every pass produces a new program every time, how many pass runs does it perform?
stats-critical-edges · number · 1 pt · 03-writing-passesA function's CFG has edges A→B, A→C, B→C, B→D, C→D (one successor slot each). How many critical
edges does print<pebble-stats> report (Definition 12.3.2)?
stats-invalidate · single · 1 pt · 03-writing-passespebble-stats counts instructions and opcodes. Which invalidation behavior is correct for its result?
- Invalidate only when the CFG set is not preserved.
- The default: invalidated unless the analysis itself (or everything) is preserved, because any instruction change can change the counts.
- Never invalidate: statistics are approximate anyway.
- Invalidate only when a dependency is invalidated.
sr-sdiv-bias · mapping · 1 pt · 03-writing-passesFor i8 values x, give the result of the naive rewrite ashr i8 %x, 3 of sdiv i8 %x, 8, for
x = -9, -8, -1 and 7 (signed decimals).
-9, -8, -1, 7sr-nsw-top · single · 1 pt · 03-writing-passesWhich rewrite of %r = mul nsw i8 %x, -128 is correct?
- %r = shl nsw i8 %x, 7
- %r = shl i8 %x, 7
- %r = sdiv i8 %x, -128
- %r = ashr i8 %x, 7
instr-counters · number · 1 pt · 03-writing-passesA function's CFG has 6 blocks, 8 edges, one entry and one exit. With the spanning-tree method
(Algorithm 12.3.7, including the virtual exit→entry edge), how many counters suffice?
instr-reconstruct · mapping · 1 pt · 03-writing-passesDiamond CFG A→B, A→C, B→D, C→D, with the virtual edge D→A. The spanning tree is {A→B, B→D, C→D};
the instrumented edges measured D→A = 10 and A→C = 3. Give the counts of AB, BD and CD.
AB, BD, CDllvm-where-sdiv-pow2 · text · 1 pt · 03-writing-passesIn llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (llvmorg-23.1.2), which DAGCombiner member function
builds the shift sequence for sdiv x, 2^k? (method name only)
fc-next-greedy · single · 1 pt · 04-filecheck-and-litInput lines: a, b, a, c. Check file: CHECK: a then CHECK-NEXT: c. What does FileCheck 23 do?
- Passes: the second
ais followed byc. - Fails at CHECK-NEXT: it matches the first
a, finds the firstcafter it on line 4, and that is not the next line. - Fails at CHECK:
aoccurs twice. - Passes: CHECK-NEXT only looks at the line after some
a.
fc-dag-not-order · single · 1 pt · 04-filecheck-and-litInput lines: b, a. Check file A: CHECK-DAG: a, CHECK-DAG: b. Check file B: CHECK-DAG: a,
CHECK-NOT: Y, CHECK-DAG: b (no Y anywhere). What happens?
- Both pass.
- A passes; B fails, because the CHECK-NOT splits the DAG group and the second group must match after the first.
- A fails, because DAG patterns must appear in order; B passes.
- Both fail.
fc-trace · mapping · 1 pt · 04-filecheck-and-litInput (numbered lines):
1 | define i32 @f(i32 %x) {
2 | %b = mul i32 %c, 8
3 | %a = icmp slt i32 %a, 2
4 | %b = shl i32 %b, 8
5 | %x = icmp slt i32 %x, 8
6 | ret i32 %b
7 | %x = mul i32 %a, 8
8 | }
Check file: (1) CHECK-DAG: %a =, (2) CHECK-DAG: slt i32 %x,, (3) CHECK: ret, (4) CHECK: },
(5) CHECK-NOT: %b 7. FileCheck passes. On which input line does each of directives 1–4 match?
1, 2, 3, 4fc-first-error · number · 1 pt · 04-filecheck-and-litInput lines: b, a. Check file: (1) CHECK-DAG: a, (2) CHECK-NOT: Y, (3) CHECK-DAG: b. Which
directive number does FileCheck report as failing?
fc-label-recovery · single · 1 pt · 04-filecheck-and-litCheck file: CHECK-LABEL: f:, CHECK: missing, CHECK-LABEL: g:, CHECK: ret on input f:, ret,
g:, ret. What does FileCheck report?
- Only the error at
CHECK: missing; the block of g is still checked and passes. - Two errors:
missingand the labelg:. - Nothing: labels make blocks optional.
- It stops at the first error without checking g.
lit-verdict · mapping · 1 pt · 04-filecheck-and-litFour lit tests: T1 has XFAIL: * and its RUN line fails; T2 has no XFAIL and its RUN line succeeds;
T3 has XFAIL: * and its RUN line succeeds; T4 has REQUIRES: nosuchfeature. Give each verdict
(PASS, FAIL, XFAIL, XPASS or UNSUPPORTED).
T1, T2, T3, T4utc-strictness · single · 1 pt · 04-filecheck-and-litA test's checks were generated by update_test_checks.py. Which change to the pass output still passes?
- An extra instruction inserted in the middle of the function.
- Renaming every occurrence of %r to %res consistently.
- Swapping two independent instructions.
- Adding an nsw flag to one instruction.
llvm-where-checkdag · text · 1 pt · 04-filecheck-and-litIn llvm/lib/FileCheck/FileCheck.cpp (llvmorg-23.1.2), which member function of FileCheckString implements
the non-overlap rule of CHECK-DAG and the checking of CHECK-NOTs between DAG groups? (name only)
diff-ub · single · 1 pt · 05-snapshot-and-differential-testingint check(int x){ return x + 1 > x; } prints 0 at -O0 and 1 at -O2 for x = INT_MAX. What does the
differential oracle tell you?
- One of the two compiler configurations is wrong.
- Nothing: the program has undefined behavior (signed overflow), so both results conform (Theorem 12.5.10).
- -O2 is wrong because -O0 is the reference.
- -O0 is wrong because it did not optimize.
diff-prob · number · 1 pt · 05-snapshot-and-differential-testingEach generated program exposes a certain bug with probability q = 0.001, independently. By Theorem 12.5.11,
what is the smallest number N of programs with e^(−qN) ≤ 0.01?
diff-matrix · mapping · 1 pt · 05-snapshot-and-differential-testingIn the lab's matrix, bug 5 makes pebble-lab-fold add an unjustified nsw flag (poison only; the same bits under
lli). For the reference checks, does each style detect it? Answer detected or passes for filecheck, snapshot,
difftest.
filecheck, snapshot, difftestsnap-false-alarm · single · 1 pt · 05-snapshot-and-differential-testingBug 4 rewrites add i32 %x, 7 as the equivalent sub i32 %x, -7. Which statement is true?
- A snapshot test passes because the program is equivalent.
- A snapshot test fails: it compares text, so every benign change is a false alarm (Proposition 12.5.9) — and so do checks generated by update_test_checks.py; a hand-written FileCheck test can accept both spellings.
- The differential tester fails.
- FileCheck cannot express alternatives.
csmith-safe · multi · 1 pt · 05-snapshot-and-differential-testingHow do Csmith and YARPGen avoid undefined behavior in the programs they generate?
- Csmith wraps signed arithmetic in safe_* functions that return a defined result instead of overflowing.
- Csmith checks pointer dereferences and side effects with analyses performed during generation.
- YARPGen computes the value of every expression while generating it and rewrites operations that would be undefined.
- Both run the program under a sanitizer and discard it if UB is reported.
yarpgen-values · single · 1 pt · 05-snapshot-and-differential-testingWhat does YARPGen's value tracking give it that Csmith's safe-math wrappers do not?
- Programs that terminate.
- Plain arithmetic operators without wrapper calls, so optimizations see the patterns they look for, while UB is still excluded for the known inputs.
- A second compiler to compare with.
- Smaller programs.
stress-oracle · single · 1 pt · 05-snapshot-and-differential-testingWhat is the test oracle when running llvm-stress | opt -O2 | llc?
- The output of running the generated function.
- That opt and llc do not crash and produce valid output; llvm-stress functions read through pointer arguments and are not meant to run.
- A checksum of global variables.
- Agreement between -O0 and -O2 executions.
diff-agree · single · 1 pt · 05-snapshot-and-differential-testingGCC and Clang produce the same wrong output for a Csmith program. What does differential testing report?
- A bug in both compilers.
- Nothing: agreement is not correctness; shared bugs are invisible to a differential oracle (Proposition 12.5.12).
- A bug in Csmith.
- An undefined behavior.
gw-extinction · number · 1 pt · 06-fuzzing-and-metamorphic-testingRandom derivations of the grammar E → E + E | x choose E + E with probability p = 3/4. What is the probability
that a derivation terminates? (Theorem 12.6.7; give two decimals.)
gw-terminate · single · 1 pt · 06-fuzzing-and-metamorphic-testingFor E → E + E | x with probability p for E + E, which choices of p give derivations that terminate with probability 1?
- p ≤ 1/2
- p < 1
- p ≤ 3/4
- p = 0 only
cov-waiting · number · 1 pt · 06-fuzzing-and-metamorphic-testingIn Theorem 12.6.8's model, a target checks k = 3 bytes in sequence. What upper bound on the expected number of
executions does the feedback fuzzer get (256·k²)?
cov-new-reduce · single · 1 pt · 06-fuzzing-and-metamorphic-testingIn libFuzzer's log, what do the NEW and REDUCE events mean?
- NEW: an input with a feature not yet in the corpus was added; REDUCE: a shorter input with the same features replaced a corpus input.
- NEW: a crash; REDUCE: the crash was minimized.
- NEW: a mutation strategy was added; REDUCE: the dictionary shrank.
- NEW: a new thread; REDUCE: a thread finished.
emi-prune · set · 1 pt · 06-fuzzing-and-metamorphic-testingA program and the statements executed on input I:
S1: s = 0 (executed)
S2: for i in 0..4: (executed)
S3: if i > 10: (executed)
S4: s = s + 100
S5: else if i == 2: (executed)
S6: s = s + 1 (executed)
S7: if s < 0: (executed)
S8: print("neg")
S9: print(s) (executed)
Which statements may an EMI variant replace by an empty statement (Definition 12.6.5)?
llvm-where-fuzzer-loop · text · 1 pt · 06-fuzzing-and-metamorphic-testingIn compiler-rt/lib/fuzzer/FuzzerLoop.cpp (llvmorg-23.1.2), which Fuzzer member function picks a corpus input,
mutates it and runs it once? (name only)
ddmin-trace · sequence · 1 pt · 07-reduction-and-bisectionEight elements 1..8; the test fails iff the configuration contains both 3 and 6. Run ddmin with the course
conventions (Algorithm 12.7.3). Give the action of every round: s<i>, c<i>, g<m> or done.
ddmin-tests · number · 1 pt · 07-reduction-and-bisectionFor the ddmin-trace instance (8 elements, failure iff {3, 6} ⊆ c), how many distinct tests does ddmin run?
ddmin-one-minimal · single · 1 pt · 07-reduction-and-bisectionddmin over lines reduced the lab's crash to 10 lines, but C-Reduce reached 4. Which statement is true?
- ddmin has a bug: its result is not 1-minimal.
- Both results are 1-minimal; 1-minimality does not imply global minimality: removing
int clamp(...) {or its}alone breaks compilation, and ddmin never removes the pair once it works on single lines. - C-Reduce's result is not interesting.
- Line granularity always gives the global minimum.
ddmin-bound · single · 1 pt · 07-reduction-and-bisectionWhat does Proposition 12.7.10 say about one failure-inducing element among N?
- ddmin needs N tests.
- ddmin finds it with at most 2⌈log₂ N⌉ tests, like binary search.
- ddmin needs N² tests.
- ddmin may fail to find it.
creduce-fixpoint · single · 1 pt · 07-reduction-and-bisectionWhen do C-Reduce and llvm-reduce stop?
- Both after one pass over the input.
- C-Reduce when a whole round of its passes makes no interesting candidate smaller; llvm-reduce when a round of its delta passes does not lower the complexity score, or after --max-pass-iterations rounds (default 5).
- Both after a fixed number of tests.
- Both when the input compiles.
llvm-reduce-valid · multi · 1 pt · 07-reduction-and-bisectionWhich statements about llvm-reduce are true?
- Every candidate it tests is valid IR: deltas repair the module so it verifies.
- Its deltas work on IR entities (functions, instructions, operands, attributes), with a chunked, ddmin-like search per kind.
- It replaced bugpoint, which LLVM 23 removed.
- It automatically decides whether a miscompilation happened, without an interestingness test.
bisect-steps · number · 1 pt · 07-reduction-and-bisectionA pipeline performs 1000 optional pass executions; the first bad one is unknown. How many -opt-bisect-limit tests does binary search need in the worst case?
bisect-limits · sequence · 1 pt · 07-reduction-and-bisectionopt -O2 performs 181 counted pass executions; the program is good for limits < 100 and bad from 100 on.
Starting with lo = 0 (good) and hi = 181 (bad), Algorithm 12.7.7 tests mid = (lo + hi) div 2 each time. List
the tested limits in order.
llvm-where-optbisect · text · 1 pt · 07-reduction-and-bisectionIn llvm/lib/IR/OptBisect.cpp (llvmorg-23.1.2), which OptBisect member function decides whether a pass execution runs? (name only)
tv-refine · mapping · 1 pt · 08-translation-validationSource %r = sdiv i4 %x, 4, target %r = ashr i4 %x, 2. For x = -7, -4, -1 and 5 (signed), does the target
refine the source on that input? Answer yes or no.
-7, -4, -1, 5tv-sound · single · 1 pt · 08-translation-validationA sound translation validator returns valid for every run of a pass on your test corpus. What follows?
- The pass is correct on all programs.
- Each validated output refines its input (and a validated pipeline's output refines the pipeline's input); nothing follows for other programs.
- The pass terminates on all programs.
- The validator is complete.
tv-poison-bug · multi · 1 pt · 08-translation-validationThe lab's bug 5 turns (x + 1) + 1 into add nsw i32 %x, 2. Which techniques detect it?
- Differential testing with lli
- Translation validation (tv.py, Alive2)
- A FileCheck line that pins the instruction without flags
- A snapshot test
necula-relation · single · 1 pt · 08-translation-validationWhat does Necula's validator infer to relate a source and an optimized target with different control flow?
- A bijection between instructions.
- A simulation relation: pairs of related program points with formulas relating source and target variables, checked path by path with verification conditions.
- A profile of executed statements.
- A minimal failing input.
necula-unknown · single · 1 pt · 08-translation-validationNecula's validator cannot prove a verification condition. What does it report, and why?
- invalid, because an unproved VC is a miscompilation
- unknown: the inferred relation or the prover may be too weak, so failure to prove is not a counterexample
- valid, because the VC is probably true
- it retries with a larger unroll bound
alive-flag · number · 1 pt · 08-translation-validationFor i8, what is the largest k such that mul nsw i8 %x, 2^k ⇒ shl nsw i8 %x, k is correct (Alive's flag question)?
alive2-unroll · single · 1 pt · 08-translation-validationalive-tv reports "The source program doesn't reach a return instruction" for a loop that runs 4 times,
with --src-unroll=2. What does this mean?
- The transformation is wrong.
- With 2 unrolled iterations no source execution returns, so the bounded check has nothing to compare; raise the bound (Proposition 12.8.12).
- The source has undefined behavior.
- Alive2 does not support loops.