Created
February 25, 2013 00:44
-
-
Save dtzWill/5026537 to your computer and use it in GitHub Desktop.
Examples of ways LLVM IR does not capture signedness information in a way that's recoverable through analysis.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <limits.h> | |
// Easy example where IR doesn't contain source-level overflow | |
// -O1: 'return a + 3*b' (no nsw flags) | |
int test1(int a, int b) { | |
return a + b + b + b; | |
} | |
// Example where signedness is lost. | |
// -O1: 'return a + b', (no nsw flags) | |
int test2(int a, int b, char test) { | |
if (a > 0 && b > 0) { | |
unsigned c = a, d = b; | |
return c + d; | |
} else | |
return a + b; | |
} | |
// Trunc/extension errors due to promotion are generally lost: | |
// 'add' in this example does not have 'nsw' flag. | |
// -O0: signext/trunc intructions exist, 32bit add has nsw flag | |
// -O1: 16bit add w/o nsw flag | |
short a, b; | |
void test3() { | |
a = b + 1; | |
} | |
// Signedness conversions don't exist at the IR level: | |
// (this is lost as soon as clang converts the code to IR) | |
int test4(unsigned a) { | |
return a + 1U; | |
} | |
// PHI's make it impossible to statically | |
// give an SSA value a single signedness: | |
char test5(unsigned a, unsigned b) { | |
int c; | |
if (a > 0) | |
c = a + b; // Unsigned add | |
else | |
c = (int)a * (int)b; // Signed multiplication | |
// c = phi(c_sign, c_unsign) <-- Signedness? | |
return (char)c; // Emit signed or unsigned truncation check? | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment