FILECHECK(1)
๐ FILECHECK(1) ๐
Okay bestie, this is the FILECHECK(1) page from the LLVM project ๐ธ The manual name is FileCheck, and it's about to get very good. Let's go โจ
โจ NAME โจ
FileCheck is a flexible pattern matching file verifier ๐
โจ SYNOPSIS โจ
FileCheck match-filename [--check-prefix=XXX] [--strict-whitespace]
โจ DESCRIPTION โจ
Okay so FileCheck reads two files ๐. One comes from standard input and one you pass on the command line, and it uses one to verify the other. This is literally the move for the testsuite ๐ฅ, since it wants to confirm that the output of some tool (like llc) has the info you expect, like a movsd from esp or whatever is giving main character energy. It's kinda like grep, but it's built for matching multiple different inputs inside one file, in a specific order ๐ฆ
The match-filename file is the one holding the patterns to match. The file being verified gets read from standard input unless you use the --input-file option ๐ซถ
โจ OPTIONS โจ
Okay, the options can come from the environment variable FILECHECK_OPTS and from the command line, so you've got two places to hide your settings ๐
-helpโ Prints a summary of the command line options ๐ธ--check-prefix prefixโ FileCheck goes hunting through match-filename for patterns, and by default they're prefixed with"CHECK:". If you want a different prefix (maybe the same input file is checking multiple different tools or options), this is your girl. Pass it without the trailing":", and you can give it one or more prefixes to match. Multiple prefixes are super useful for tests that change between run options while most lines stay the same ๐ง
FileCheck does not permit duplicate prefixes, even if one is a check prefix and one is a comment prefix (see --comment-prefixes below). No copycats allowed ๐
โโ๏ธ
--check-prefixes prefix1,prefix2,...โ An alias of--check-prefixthat lets you list multiple prefixes as a comma separated list. Same energy, just more prefixes in one go โจ--comment-prefixes prefix1,prefix2,...โ By default, FileCheck ignores any occurrence in match-filename of any check prefix if it's preceded on the same line by"COM:"or"RUN:". See the section The "COM:" directive for usage details ๐ญ
You can override these default comment prefixes with --comment-prefixes if they don't fit your testing environment. Honestly though, doing that is not recommended in LLVM's LIT-based test suites. Those should be easier to maintain when everyone follows a consistent comment style. If the defaults aren't working for you, consider proposing a change to the default comment prefixes instead ๐ซ
--input-file filenameโ The file to check. Defaults to stdin ๐ฅ--match-full-linesโ By default, FileCheck allows matches anywhere on a line. This option requires all positive matches to cover an entire line. Leading and trailing whitespace is ignored, unless--strict-whitespaceis also specified. (Note: negative matches fromCHECK-NOTare not affected by this option!) ๐
Passing this option is equivalent to inserting {{^ *}} or {{^}} before, and {{ *$}} or {{$}} after, every positive check pattern.
--strict-whitespaceโ By default, FileCheck canonicalizes input horizontal whitespace (spaces and tabs), so it ignores those differences. A space will match a tab, which is lowkey iconic. This flag turns that behavior off. End-of-line sequences are canonicalized to UNIX-style\nin all modes, no matter what ๐--ignore-caseโ By default, FileCheck uses case-sensitive matching. This option makes it use case-insensitive matching instead ๐--implicit-check-not check-patternโ Adds implicit negative checks for the specified patterns between positive checks. This lets you write stricter tests without stuffing them full ofCHECK-NOTs. Ate and left no crumbs ๐
For example, --implicit-check-not warning: can be super useful when you're testing diagnostic messages from tools that don't have an option similar to clang -verify. With this option, FileCheck verifies that the input doesn't contain any warnings that aren't covered by a CHECK: pattern ๐
--dump-input <value>โ Dumps the input to stderr, adding annotations that represent the currently enabled diagnostics. If you use this option multiple times, the<value>that appears earliest in the list below wins. The default isfail๐helpโ Explains the input dump and quitsalwaysโ Always dumps the inputfailโ Dumps the input on failureneverโ Never dumps the input
--dump-input-context <N>โ In the dump requested by--dump-input, prints<N>input lines before and<N>input lines after any lines specified by--dump-input-filter. If you use this option multiple times, the largest specified<N>takes precedence. The default is5๐ง--dump-input-filter <value>โ In the dump requested by--dump-input, prints only the input lines of kind<value>, plus any context specified by--dump-input-context. If you use this option multiple times, the<value>that appears earliest in the list below has precedence. The default iserrorwhen--dump-input=fail, and it'sallwhen--dump-input=always๐allโ All input linesannotation-fullโ Input lines with annotationsannotationโ Input lines with starting points of annotationserrorโ Input lines with starting points of error annotations
--enable-var-scopeโ Enables scope for regex variables ๐ฆ
Variables with names that start with $ are considered global and stay set throughout the whole file. All other variables get undefined after each CHECK-LABEL they run into ๐ง
-D<VAR=VALUE>โ Sets a FileCheck pattern variableVARwith the valueVALUE, which you can then use inCHECK:lines ๐-D#<FMT>,<NUMVAR>=<NUMERIC EXPRESSION>โ Sets a FileCheck numeric variableNUMVARof matching formatFMTto the result of evaluating<NUMERIC EXPRESSION>, which you can use inCHECK:lines. See the section FileCheck Numeric Variables and Expressions for details on the supported numeric expressions ๐ข-versionโ Shows the version number of this program โจ-vโ Prints good directive pattern matches. However, if-dump-input=failor-dump-input=alwaysis set, it adds those matches as input annotations instead ๐-vvโ Prints information that helps diagnose internal FileCheck issues, like discarded overlappingCHECK-DAG:matches, implicit EOF pattern matches, andCHECK-NOT:patterns that don't have any matches. Implies-v. However, if-dump-input=failor-dump-input=alwaysis set, it just adds that information as input annotations instead ๐ต๏ธโโ๏ธ--allow-deprecated-dag-overlapโ Enables overlapping among matches in a group of consecutiveCHECK-DAG:directives.
Heads up bestie, this one is deprecated! It's only here for convenience while old tests get migrated to the new non-overlapping CHECK-DAG: implementation ๐จ
--colorโ Uses colors in the output. It's autodetected by default ๐
; COM: FIXME: X64 isn't working correctly yet for this part of codegen, but
; COM: X64 will have something similar to X32:
; COM:
; COM: X64: pinsrd_1:
; COM: X64: pinsrd $1, %edi, %xmm0
Without COM:, you'd have to reword stuff and mangle the directive syntax just so FileCheck doesn't mistake the commented-out X32: and X64: bits for real directives ๐ญ. There have also been proposals for FileCheck diagnostics that might yell at those X64 mentions lacking the trailing :, since they look like directive typos. Dodging all of that is tedious for the test author, and mangling directive syntax can make the purpose of the test code super unclear. COM: avoids all these problems ๐ซถ
A few important usage notes, bestie ๐ :
COM:inside another directive's pattern does NOT comment out the rest of that pattern. For example:; X32: pinsrd $1, 4(%esp), %xmm0 COM: This is part of the X32 pattern!๐ If you need to temporarily comment out part of a directive's pattern, move it to another line. The reason is that FileCheck parsesCOM:the same way as any other directive, so only the first directive on the line gets recognized ๐ง- For the sake of LIT, FileCheck treats
RUN:just likeCOM:. If that's not suitable for your test environment, see--comment-prefixes. ๐ธ - FileCheck does not recognize
COM,RUN, or any user-defined comment prefix as a comment directive when it's combined with one of the usual check directive suffixes, such as-NEXT:or-NOT:(we'll get to those below). Instead, FileCheck treats that combo as plain text ๐. If it needs to act as a comment directive for your test environment, define it as one with--comment-prefixes.
๐ฆ The "CHECK-NEXT:" directive
Sometimes you want to match lines and verify that the matches happen on exactly consecutive lines, with no other lines in between. That's where CHECK: and CHECK-NEXT: come in, bestie ๐ If you specified a custom check prefix, just use <PREFIX>-NEXT:. Here's an example that works exactly how you'd expect โจ
define void @t2(<2 x double>* %r, <2 x double>* %A, double %B) {
%tmp3 = load <2 x double>* %A, align 16
%tmp7 = insertelement <2 x double> undef, double %B, i32 0
%tmp9 = shufflevector <2 x double> %tmp3,
<2 x double> %tmp7,
<2 x i32> < i32 0, i32 2 >
store <2 x double> %tmp9, <2 x double>* %r, align 16
ret void
; CHECK: t2:
; CHECK: movl 8(%esp), %eax
; CHECK-NEXT: movapd (%eax), %xmm0
; CHECK-NEXT: movhpd 12(%esp), %xmm0
; CHECK-NEXT: movl 4(%esp), %eax
; CHECK-NEXT: movapd %xmm0, (%eax)
; CHECK-NEXT: ret
}
CHECK-NEXT: directives are picky ๐ They reject the input unless there is exactly one newline between them and the previous directive. And a CHECK-NEXT: cannot be the first directive in a file.
๐ The "CHECK-SAME:" directive
Sometimes you want matches to happen on the same line as the previous match. For that, use CHECK: and CHECK-SAME: ๐ If you specified a custom check prefix, just use <PREFIX>-SAME:.
CHECK-SAME: is seriously powerful when you pair it with CHECK-NOT: (also coming up below) ๐ฅ For example, this one works like you'd expect:
!0 = !DILocation(line: 5, scope: !1, inlinedAt: !2)
; CHECK: !DILocation(line: 5,
; CHECK-NOT: column:
; CHECK-SAME: scope: ![[SCOPE:[0-9]+]]
CHECK-SAME: directives reject the input if there are any newlines between them and the previous directive. And yep, a CHECK-SAME: cannot be the first directive in a file either ๐ฅบ
๐ง The "CHECK-EMPTY:" directive
If you need to check that the next line has absolutely nothing on it, not even whitespace, the CHECK-EMPTY: directive is your bestie ๐
declare void @foo()
declare void @bar()
; CHECK: foo
; CHECK-EMPTY:
; CHECK-NEXT: bar
Just like CHECK-NEXT:, this directive will fail if there's more than one newline before it finds the next blank line. And it cannot be the first directive in a file.
๐ The "CHECK-NOT:" directive
The CHECK-NOT: directive is used to verify that a string does not occur between two matches (or before the first match, or after the last match) ๐ For example, if you want to verify that a load gets removed by a transformation, a test like this does the job:
define i8 @coerce_offset0(i32 %V, i32* %P) {
store i32 %V, i32* %P
%P2 = bitcast i32* %P to i8*
%P3 = getelementptr i8* %P2, i32 2
%A = load i8* %P3
ret i8 %A
; CHECK: @coerce_offset0
; CHECK-NOT: load
; CHECK: ret i8
}
๐ The "CHECK-COUNT:" directive
If you need to match multiple lines with the same pattern over and over again, you can just repeat a plain CHECK: as many times as you need ๐ If that feels too boring, you can use a counted check instead: CHECK-COUNT-<num>:, where <num> is a positive decimal number. It matches the pattern exactly <num> times, no more and no less ๐ฏ If you specified a custom check prefix, just use <PREFIX>-COUNT-<num>: for the same effect. Here's a simple example:
Loop at depth 1
Loop at depth 1
Loop at depth 1
Loop at depth 1
Loop at depth 2
Loop at depth 3
; CHECK-COUNT-6: Loop at depth {{[0-9]+}}
; CHECK-NOT: Loop at depth {{[0-9]+}}
๐ธ The "CHECK-DAG:" directive
If you need to match strings that don't show up in a strictly sequential order, CHECK-DAG: can verify them between two matches (or before the first match, or after the last match) ๐ง For example, clang emits vtable globals in reverse order. With CHECK-DAG:, we can keep the checks in the natural order โจ
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
struct Foo { virtual void method(); };
Foo f; // emit vtable
// CHECK-DAG: @_ZTV3Foo =
struct Bar { virtual void method(); };
Bar b;
// CHECK-DAG: @_ZTV3Bar =
CHECK-NOT: directives can be mixed in with CHECK-DAG: directives to exclude strings between the surrounding CHECK-DAG: directives. As a result, those surrounding CHECK-DAG: directives can't be reordered. In other words, all occurrences matching a CHECK-DAG: before the CHECK-NOT: must not fall behind occurrences matching a CHECK-DAG: after the CHECK-NOT:. For example:
; CHECK-DAG: BEFORE
; CHECK-NOT: NOT
; CHECK-DAG: AFTER
This case will reject input strings where BEFORE occurs after AFTER ๐
โโ๏ธ
With captured variables, CHECK-DAG: can match valid topological orderings of a DAG, with edges going from the definition of a variable to its use ๐ฆ It's super useful when your test cases need to match different output sequences from the instruction scheduler. For example:
; CHECK-DAG: add [[REG1:r[0-9]+]], r1, r2
; CHECK-DAG: add [[REG2:r[0-9]+]], r3, r4
; CHECK: mul r5, [[REG1]], [[REG2]]
In this case, any order of those two add instructions will be allowed ๐ซถ
If you are defining and using variables in the same CHECK-DAG: block, be aware that the definition rule can match after its use. So, for instance, the code below will pass:
; CHECK-DAG: vmov.32 [[REG2:d[0-9]+]][0]
; CHECK-DAG: vmov.32 [[REG2]][1]
vmov.32 d0[1]
vmov.32 d0[0]
While this other code will not:
; CHECK-DAG: vmov.32 [[REG2:d[0-9]+]][0]
; CHECK-DAG: vmov.32 [[REG2]][1]
vmov.32 d1[1]
vmov.32 d0[0]
โ ๏ธ While this can be very useful, it's also dangerous, bestie ๐ญ In the case of a register sequence, you must have a strong order (read before write, copy before use, etc.). If the definition your test is looking for doesn't match (because of a bug in the compiler), it may match further away from the use and mask real bugs. In those cases, to enforce the order, use a non-DAG directive between DAG-blocks.
A CHECK-DAG: directive skips matches that overlap the matches of any preceding CHECK-DAG: directives in the same CHECK-DAG: block. This non-overlapping behavior is consistent with other directives, and it's also necessary to handle sets of non-unique strings or patterns ๐งฉ For example, the following directives look for unordered log entries for two tasks in a parallel program, such as the OpenMP runtime:
// CHECK-DAG: [[THREAD_ID:[0-9]+]]: task_begin
// CHECK-DAG: [[THREAD_ID]]: task_end
//
// CHECK-DAG: [[THREAD_ID:[0-9]+]]: task_begin
// CHECK-DAG: [[THREAD_ID]]: task_end
The second pair of directives is guaranteed not to match the same log entries as the first pair, even though the patterns are identical and even if the text of the log entries is identical, because the thread ID manages to be reused ๐คฏ
๐ The "CHECK-LABEL:" directive
Sometimes you've got a file with multiple tests divided into logical blocks, and one or more CHECK: directives may accidentally succeed by matching lines in a later block ๐ต An error will usually get generated eventually, but the check flagged as causing it may not actually have anything to do with the real source of the problem.
To get better error messages in these cases, use the CHECK-LABEL: directive ๐
It's treated identically to a normal CHECK directive, except FileCheck makes an extra assumption: a line matched by the directive cannot also be matched by any other check present in match-filename. This is meant for lines containing labels or other unique identifiers ๐ท๏ธ Conceptually, a CHECK-LABEL divides the input stream into separate blocks, each processed independently, which stops a CHECK: in one block from matching a line in another block. If --enable-var-scope is in effect, all local variables get cleared at the beginning of the block.
For example:
define %struct.C* @C_ctor_base(%struct.C* %this, i32 %x) {
entry:
; CHECK-LABEL: C_ctor_base:
; CHECK: mov [[SAVETHIS:r[0-9]+]], r0
; CHECK: bl A_ctor_base
; CHECK: mov r0, [[SAVETHIS]]
%0 = bitcast %struct.C* %this to %struct.A*
%call = tail call %struct.A* @A_ctor_base(%struct.A* %0)
%1 = bitcast %struct.C* %this to %struct.B*
%call2 = tail call %struct.B* @B_ctor_base(%struct.B* %1, i32 %x)
ret %struct.C* %this
}
define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
entry:
; CHECK-LABEL: D_ctor_base:
The use of CHECK-LABEL: here is what keeps those three CHECK: directives in line ๐ซถ they only accept lines from the body of the @C_ctor_base function, even if their patterns also match lines way later in the file ๐. And if one of the three CHECK: directives fails, FileCheck doesn't give up. It recovers by moving on to the next block, so you can catch multiple test failures in one invocation ๐
No rule says CHECK-LABEL: has to contain strings that match real syntactic labels in a source or output language ๐ It just has to uniquely match a single line in the file being verified. That's the whole vibe โจ
๐ซ Heads up: CHECK-LABEL: directives cannot contain variable definitions or uses.
โจ FileCheck Regex Matching Syntax
Every FileCheck directive takes a pattern to match ๐ For most things, plain fixed string matching is perfectly sufficient. For the times you need something more flexible, you can write a regular expression inside double braces, like {{yourregex}}. FileCheck implements a POSIX regular expression matcher and supports Extended POSIX regular expressions (ERE). Since fixed string matching is what we use most of the time, FileCheck is built to mix and match it with regexes, so you can write stuff like this:
; CHECK: movhpd {{[0-9]+}}(%esp), {{%xmm[0-7]}}
In this case, any offset from the ESP register is allowed, and any xmm register is allowed too ๐ฆ
Regexes live inside double braces, so they stand out visually, and you don't need escape characters inside them the way you would in C ๐ The rare time you want to match double braces literally from the input, you can use something ugly like {{[}][}]}} as your pattern ๐ And if you're using the repetition count syntax, like [[:xdigit:]]{8} to match exactly 8 hex digits, wrap it in parentheses like {{([[:xdigit:]]{8})}} so it doesn't get confused with FileCheck's closing double-brace ๐ซถ
โจ FileCheck String Substitution Blocks
It's super useful to match a pattern and then check that it shows up again later in the file ๐ For codegen tests, this lets you allow any register but verify that the same register is used consistently later. That's what string substitution blocks are for. FileCheck lets you define string variables and substitute them into patterns. Here's a simple example:
; CHECK: test5:
; CHECK: notw [[REGISTER:%[a-z]+]]
; CHECK: andw {{.*}}[[REGISTER]]
The first check line matches the regex %[a-z]+ and captures it into the string variable REGISTER. The second line verifies that whatever is in REGISTER shows up later in the file after an andw ๐ฅ String substitution blocks are always wrapped in [[ ]] pairs, and variable names can be formed with the regex [a-zA-Z_][a-zA-Z0-9_]*. If a colon follows the name, it's a definition. Otherwise, it's a substitution โจ
FileCheck variables can be defined multiple times, and substitutions always grab the latest value ๐ Variables can also be substituted later on the same line they were defined on. For example:
; CHECK: op [[REG:r[0-9]+]], [[REG]]
This is handy if you want the operands of op to be the same register and don't care exactly which register it is ๐ง
If --enable-var-scope is in effect, variables with names starting with $ are considered global, and all others are local. All local variables get undefined at the beginning of each CHECK-LABEL block. Global variables aren't affected by CHECK-LABEL. This makes it way easier to make sure individual tests aren't affected by variables set in preceding tests ๐
โจ FileCheck Numeric Substitution Blocks
FileCheck also has numeric substitution blocks ๐ข You can define numeric variables and check for numeric values that satisfy a numeric expression constraint based on those variables, using a numeric substitution. This lets CHECK: directives verify a numeric relationship between two numbers, like making sure consecutive registers are used โญ
The syntax to define a numeric variable is [[#%<fmtspec>,<NUMVAR>:]], where:
%<fmtspec>is an optional scanf-style matching format specifier that tells FileCheck what number format to match, like a hex number ๐ธ Right now the accepted format specifiers are%u,%d,%xand%X. If it's left out, the format specifier defaults to%u.<NUMVAR>is the name of the numeric variable that gets set to the matching value ๐
For example:
; CHECK: mov r[[#REG:]], 0x[[#%X,IMM:]]
would match mov r5, 0xF0F0 and set REG to the value 5 and IMM to the value 0xF0F0 ๐
The syntax for a numeric substitution is [[#%<fmtspec>: <constraint> <expr>]], where:
%<fmtspec>is the same matching format specifier you use when defining numeric variables, but here it acts as a printf-style format showing how a numeric expression value should be matched. If it's left out, the format specifier gets inferred from the matching format of the numeric variable(s) the expression constraint uses, if any. If no numeric variable is used, it defaults to%u. If several numeric variables have conflicting matching formats, the format specifier is mandatory ๐<constraint>describes how the value to match has to relate to the value of the numeric expression. The only accepted constraint right now is==for an exact match, and it's the default if<constraint>isn't provided. No matching constraint can be specified when the<expr>is empty ๐ซถ<expr>is an expression ๐งฎ An expression is recursively defined as:- a numeric operand, or
- an expression followed by an operator and a numeric operand.
A numeric operand is a previously defined numeric variable, an integer literal, or a function. Spaces are accepted before, after and between any of these elements. Numeric operands have 64-bit precision. Overflow and underflow are rejected. There's no support for operator precedence, but you can use parentheses to change the evaluation order ๐
The supported operators are:
+โ returns the sum of its two operands โ-โ returns the difference of its two operands โ
The syntax of a function call is <name>(<arguments>), where:
nameis a predefined string literal. The accepted values are:addโ returns the sum of its two operands.divโ returns the quotient of its two operands.maxโ returns the largest of its two operands.minโ returns the smallest of its two operands.mulโ returns the product of its two operands.subโ returns the difference of its two operands.
<arguments>is a comma separated list of expressions ๐
For example:
; CHECK: load r[[#REG:]], [r0]
; CHECK: load r[[#REG+1]], [r1]
; CHECK: Loading from 0x[[#%x,ADDR:]]
; CHECK-SAME: to 0x[[#ADDR + 7]]
The above example would match this text:
load r5, [r0]
load r6, [r1]
Loading from 0xa0463440 to 0xa0463447
but would not match this text:
load r5, [r0]
load r7, [r1]
Loading from 0xa0463440 to 0xa0463443
Why? Because 7 is unequal to 5 + 1, and a0463443 is unequal to a0463440 + 7 ๐ญ
The syntax also supports an empty expression, which is equivalent to writing {{[0-9]+}}. Use it when the input must contain a numeric value but the value itself doesn't matter ๐
; CHECK-NOT: mov r0, r[[#]]
This checks that a value is synthesized rather than moved around ๐ง
A numeric variable can also be defined as the result of a numeric expression. In that case, the numeric expression constraint is checked, and if it's verified, the variable gets assigned that value. The unified syntax for defining numeric variables and checking a numeric expression is [[#%<fmtspec>,<NUMVAR>: <constraint> <expr>]], with each element described above. You can use this to make a testcase more self-describing by using variables instead of values ๐
; CHECK: mov r[[#REG_OFFSET:]], 0x[[#%X,FIELD_OFFSET:12]]
; CHECK-NEXT: load r[[#]], [r[[#REG_BASE:]], r[[#REG_OFFSET]]]
which would match:
mov r4, 0xC
load r6, [r5, r4]
The --enable-var-scope option has the same effect on numeric variables as it does on string variables โจ
โ ๏ธ Important note: In its current implementation, an expression cannot use a numeric variable defined earlier in the same CHECK directive.
โจ FileCheck Pseudo Numeric Variables
Sometimes you need to verify output that contains line numbers from the match file, like when you're testing compiler diagnostics ๐ The catch is that this makes the match file fragile, because CHECK: lines contain absolute line numbers in the same file, and those have to be updated whenever line numbers change because of text being added or deleted ๐ฉ
To make this easier, FileCheck expressions understand the @LINE pseudo numeric variable, which evaluates to the line number of the CHECK pattern where it's found ๐ธ That means your match patterns can sit right next to the relevant test lines and use relative line number references, like this:
// CHECK: test.cpp:[[# @LINE + 4]]:6: error: expected ';' after top level declarator
// CHECK-NEXT: {{^int a}}
// CHECK-NEXT: {{^ \^}}
// CHECK-NEXT: {{^ ;}}
int a
For legacy uses of @LINE as a special string variable, FileCheck also accepts these forms with string substitution block syntax: [[@LINE]], [[@LINE+<offset>]] and [[@LINE-<offset>]]. They have no spaces inside the brackets, and offset is an integer ๐ฆ
โจ Matching Newline Characters
To match newline characters in regular expressions, you can use the character class [[:space:]] ๐ซง For example, this pattern:
// CHECK: DW_AT_location [DW_FORM_sec_offset] ([[DLOC:0x[0-9a-f]+]]){{[[:space:]].*}}"intd"
matches output of this form (from llvm-dwarfdump):
DW_AT_location [DW_FORM_sec_offset] (0x00000233)
DW_AT_name [DW_FORM_strp] ( .debug_str[0x000000c9] = "intd")
This lets us set the FileCheck variable DLOC to the desired value 0x00000233, extracted from the line immediately preceding "intd" ๐
โจ AUTHOR โจ
Maintained by the LLVM Team (https://llvm.org/) ๐
โจ COPYRIGHT โจ
2003-2024, LLVM Project ๐
Okay bestie, that's the whole page ๐ซถ Footer says FILECHECK(1), version 11, dated 2024-07-18. Go slay your tests! ๐ โจ
๐ฆ where this page comes from
- fedora 43: llvm11 11.1.0-14.fc41 ยท NCSA
- fedora 43: llvm11 11.1.0-14.fc41 ยท NCSA
- fedora 44: llvm11 11.1.0-14.fc41 ยท NCSA
- fedora 44: llvm11 11.1.0-14.fc41 ยท NCSA
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms