The document discusses how inline assembly is processed in Clang and LLVM. It outlines the target-specific logic involved at each stage, including operand constraint validation in Clang, lowering operands to LLVM IR, and printing different operand types in the assembler. Target-specific callbacks for inline assembly handling are scattered throughout Clang and LLVM. The goals are to learn the inline assembly workflow and provide documentation for backend developers to add support.
Report
Share
Report
Share
1 of 112
Download to read offline
More Related Content
Handling inline assembly in Clang and LLVM
1. Min-Yih “Min” Hsu @ LLVM Dev Meeting 2021
Handling inline assembly
in Clang and LLVM
2. about:me
“Min” Hsu
• Computer Science PhD Candidate in
University of California, Irvine
• Code owner of M68k LLVM backend
• Author of book “LLVM Techniques,
Tips and Best Practices” (2021)
2
34. Handling inline assembly in Clang & LLVM
Background
• Most parts of an inline assembly string are simply copied into the
fi
nal
assembly
fi
le
14
35. Handling inline assembly in Clang & LLVM
Background
• Most parts of an inline assembly string are simply copied into the
fi
nal
assembly
fi
le
• LLVM needs to “glue” inline assembly operands with the surrounding code
14
36. Handling inline assembly in Clang & LLVM
Background
• Most parts of an inline assembly string are simply copied into the
fi
nal
assembly
fi
le
• LLVM needs to “glue” inline assembly operands with the surrounding code
• Lots of target-speci
fi
c logics
• In both Clang and the backend
14
37. Handling inline assembly in Clang & LLVM
Background
• Most parts of an inline assembly string are simply copied into the
fi
nal
assembly
fi
le
• LLVM needs to “glue” inline assembly operands with the surrounding code
• Lots of target-speci
fi
c logics
• In both Clang and the backend
• Target-speci
fi
c callbacks are scattered in the codebase
• Documentation for this part is a little…shy
14
42. Outline of target-specific logics in each stage
16
Clang
Lowering
LLVM IR
Machine IR
AsmPrinter
• Simple validation on operand constraints
• Converting constraints
43. Outline of target-specific logics in each stage
16
Clang
Lowering
LLVM IR
Machine IR
AsmPrinter
• Simple validation on operand constraints
• Converting constraints
• Classifying constraints
• Constraint validations
• Lowering the operands
44. Outline of target-specific logics in each stage
16
Clang
Lowering
LLVM IR
Machine IR
AsmPrinter
• Simple validation on operand constraints
• Converting constraints
• Classifying constraints
• Constraint validations
• Lowering the operands
Print out di
ff
erent types of operands
45. Outline of target-specific logics in each stage
17
Clang
Lowering
LLVM IR
Machine IR
AsmPrinter
• Simple validation on operand constraints
• Converting constraints
• Classifying constraints
• Constraint validations
• Lowering the operands
Print out di
ff
erent types of operands
50. Operand constraint validations in Clang
Limitation on immediate value validations
20
void foo() {
int32_t x;
asm ("move.l %0, %%d1" : : "J" (x));
}
Constant signed 16-bit integer
* M68k assembly w/ Motorola syntax
51. Operand constraint validations in Clang
Limitation on immediate value validations
20
void foo() {
int32_t x;
asm ("move.l %0, %%d1" : : "J" (x));
}
$ clang -target m68k -fsyntax-only foo.c
# No error
$ clang -target m68k -emit-llvm foo.c
# No error
Constant signed 16-bit integer
* M68k assembly w/ Motorola syntax
52. Operand constraint validations in Clang
Limitation on immediate value validations
20
void foo() {
int32_t x;
asm ("move.l %0, %%d1" : : "J" (x));
}
$ clang -target m68k -fsyntax-only foo.c
# No error
$ clang -target m68k -emit-llvm foo.c
# No error
Constant signed 16-bit integer
$ clang -target m68k -S foo.c
error: constraint 'J' expects an integer constant expression
* M68k assembly w/ Motorola syntax
53. Inline assembly in LLVM IR
21
void foo() {
const int x = 87;
asm ("move.l %0, %%d1" : : "Ci" (x) : "d1");
}
C/C++
* M68k assembly w/ Motorola syntax
54. Inline assembly in LLVM IR
21
void foo() {
const int x = 87;
asm ("move.l %0, %%d1" : : "Ci" (x) : "d1");
}
C/C++
call void asm sideeffect "move.l $0, %d1", “^Ci,~{d1}“(i32 87)
LLVM IR
* M68k assembly w/ Motorola syntax
55. Inline assembly in LLVM IR
21
void foo() {
const int x = 87;
asm ("move.l %0, %%d1" : : "Ci" (x) : "d1");
}
C/C++
call void asm sideeffect "move.l $0, %d1", “^Ci,~{d1}“(i32 87)
LLVM IR
* M68k assembly w/ Motorola syntax
56. Inline assembly in LLVM IR
21
void foo() {
const int x = 87;
asm ("move.l %0, %%d1" : : "Ci" (x) : "d1");
}
C/C++
call void asm sideeffect "move.l $0, %d1", “^Ci,~{d1}“(i32 87)
LLVM IR
* M68k assembly w/ Motorola syntax
57. Inline assembly in LLVM IR
21
void foo() {
const int x = 87;
asm ("move.l %0, %%d1" : : "Ci" (x) : "d1");
}
C/C++
call void asm sideeffect "move.l $0, %d1", “^Ci,~{d1}“(i32 87)
LLVM IR
* M68k assembly w/ Motorola syntax
58. Inline assembly in LLVM IR
21
void foo() {
const int x = 87;
asm ("move.l %0, %%d1" : : "Ci" (x) : "d1");
}
C/C++
call void asm sideeffect "move.l $0, %d1", “^Ci,~{d1}“(i32 87)
LLVM IR
* M68k assembly w/ Motorola syntax
59. Outline of target-specific logics in each stage
22
Clang
Lowering
LLVM IR
Machine IR
AsmPrinter
• Simple validation on operand constraints
• Converting constraints
• Classifying constraints
• Constraint validations
• Lowering the operands
Print out di
ff
erent types of operands
76. Lowering register operands
26
std::pair<unsigned, const TargetRegisterClass *>
TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint,
MVT VT) const;
A speci
fi
c register or 0 if not applicable
77. Lowering register operands
26
std::pair<unsigned, const TargetRegisterClass *>
TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint,
MVT VT) const;
A speci
fi
c register or 0 if not applicable Valid register class to select from
95. Outline of target-specific logics in each stage
38
Clang
Lowering
LLVM IR
Machine IR
AsmPrinter
• Simple validation on operand constraints
• Converting constraints
• Classifying constraints
• Constraint validations
• Lowering the operands
Print out di
ff
erent types of operands
108. Converting constraints in Clang
46
An operand constraint is assumed to have only a single character by default
109. Converting constraints in Clang
46
An operand constraint is assumed to have only a single character by default
Example: “Ci”
110. Converting constraints in Clang
46
An operand constraint is assumed to have only a single character by default
Example: “Ci” -> “^Ci”
111. Converting constraints in Clang
46
std::string
M68kTargetInfo::convertConstraint(const char *&Constraint) const override {
if (*Constraint == 'C')
// Two-character constraint; add "^" hint for later parsing
return std::string("^") + std::string(Constraint++, 2);
return std::string(1, *Constraint);
}
An operand constraint is assumed to have only a single character by default
Example: “Ci” -> “^Ci”
112. Operand constraint validations in Clang
Limitation on immediate value validations (cont’d)
47
bool M68kTargetInfo::validateAsmConstraint(const char *&Name, ConstraintInfo &info) const {
switch (*Name) {
…
case 'C':
++Name;
switch (*Name) {
case 'i': // constant integer
case 'j': // integer constant that doesn't fit in 16 bits
info.setRequiresImmediate();
return true;
}
break;
}
…
}