<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW " title="NEW --- - Constant not propagated into inline assembly, results in "constraint 'I' expects an integer constant expression"" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24226&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=0R0nqIu-0JNIt6qs6k7wL7I3JhKebZWdXE2YDVJWQ1k&s=oReIVDxtAvGN1nXICjFZS62YbQJeRJgQqKI7P1BBjoQ&e=">24226</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Constant not propagated into inline assembly, results in "constraint 'I' expects an integer constant expression"
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>3.6
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Driver
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>noloader@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Attempting to compile the following program using the integrated assembler
results in:
$ clang++ -g2 -O3 clang-test.cpp -o clang-test.exe
clang-test.cpp:16:11: error: invalid operand for inline asm constraint 'I'
__asm__ ("rorl %1, %0" : "+mq" (value) : "I" ((unsigned char)(rot...
^
1 error generated.
It appears the integrated assembler does not receive the const value "2". Even
2%32 is constant because the preprocessor can perform the math.
The program is OK on other Linux OS's using GCC/GAS.
**********
// clang++ -g2 -O3 clang-test.cpp -o clang-test.exe
unsigned int RightRotate(unsigned int value, unsigned int rotate);
int main(int argc, char* argv[])
{
return RightRotate(argc, 2);
}
unsigned int RightRotate(unsigned int value, unsigned int rotate)
{
// x = value; y = rotate
// The I constraint ensures we use the immediate-8 variant of the
// rotate amount y. However, y must be in [0, 31] inclusive. We
// rely on the preprocessor to propagate the constant and perform
// the modular reduction so the assembler generates the instruction.
__asm__ ("rorl %1, %0" : "+mq" (value) : "I" ((unsigned char)(rotate%32)));
return value;
}
**********
Applies to both:
$ /usr/local/bin/clang++ -v
clang version 3.6.0 (tags/RELEASE_360/final)
Target: x86_64-apple-darwin12.6.0
And
$ clang++ -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin12.6.0
**********
We are jumping through these hoops because the cryptographers often call out
specs that are not sympathetic to hardware and standards.
**********
The real code is hairier, and it involves a well defined template
implementations that avoids branching (i.e., all instructions always execute
and it C/C++ avoids undefined behavior):
// Well defined for all y, near constant time
template <class T> inline T rotrImmediateMod(T x, unsigned int y)
{
static const unsigned int THIS_SIZE = sizeof(T)*8;
y %= THIS_SIZE;
return T((x>>y) | (x<<((THIS_SIZE-y) % THIS_SIZE)));
}
Combined with specializations:
template<> inline word32 rotrImmediateMod<word32>(word32 x, unsigned int y)
{
__asm__ ("rorl %1, %0" : "+g" (x) : "I" ((unsigned char)(y%32)));
return x;
}
**********
I'll send a case of Heinekens anywhere in the world to the first person who
provides a near constant time intrinsic for left- and right-rotate. I'm amazed
Clang does not provide one
(<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_docs_LangRef.html-23intrinsic-2Dfunctions&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=0R0nqIu-0JNIt6qs6k7wL7I3JhKebZWdXE2YDVJWQ1k&s=y28iObuG8P8wAun8qD8NPwGzVOfgw7EiwlpC0l-VMxc&e=">http://llvm.org/docs/LangRef.html#intrinsic-functions</a>).
With the intrinsic, we avoid all the C/C++ undefined behavior, we avoid the
branching, we get the 1 ASM instruction speedup, and we avoid all the hassles
of inline assembly.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>