mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
C++: IR translation for binary conditional operator
IR generation was not handling the special two-operand flavor of the `?:` operator that GCC supports as an extension. The extractor doesn't quite give us enough information to do this correctly (see github/codeql-c-extractor-team#67), but we can get pretty close. About half of the code could be shared between the two-operand and three-operand flavors. The main differences for the two-operand flavor are: 1. The "then" operand isn't a child of the `ConditionalExpr`. Instead, we just reuse the original value of the "condition" operand, skipping any implicit cast to `bool` (see comment for rationale). 2. For the three-operand flavor, we generate the condition as control flow rather than the computation of a `bool` value, to avoid creating unnecessarily complicated branching. For the two-operand version, we just compute the value, since we have to reuse that value in the "then" branch anyway. I've added IR tests for these new cases. I've also updated the expectations for `SignAnalysis.ql` based on the fix. @rdmarsh2, can you please double-check that these diffs look correct? I believe they do, but you're the range/sign analysis expert.
This commit is contained in:
@@ -10265,6 +10265,224 @@ ir.cpp:
|
||||
# 1296| 1: [VariableAccess] y
|
||||
# 1296| Type = [IntType] int
|
||||
# 1296| ValueCategory = prvalue(load)
|
||||
# 1299| [TopLevelFunction] void gccBinaryConditional(bool, int, long)
|
||||
# 1299| params:
|
||||
# 1299| 0: [Parameter] b
|
||||
# 1299| Type = [BoolType] bool
|
||||
# 1299| 1: [Parameter] x
|
||||
# 1299| Type = [IntType] int
|
||||
# 1299| 2: [Parameter] y
|
||||
# 1299| Type = [LongType] long
|
||||
# 1299| body: [Block] { ... }
|
||||
# 1300| 0: [DeclStmt] declaration
|
||||
# 1300| 0: [VariableDeclarationEntry] definition of z
|
||||
# 1300| Type = [IntType] int
|
||||
# 1300| init: [Initializer] initializer for z
|
||||
# 1300| expr: [VariableAccess] x
|
||||
# 1300| Type = [IntType] int
|
||||
# 1300| ValueCategory = prvalue(load)
|
||||
# 1301| 1: [ExprStmt] ExprStmt
|
||||
# 1301| 0: [AssignExpr] ... = ...
|
||||
# 1301| Type = [IntType] int
|
||||
# 1301| ValueCategory = lvalue
|
||||
# 1301| 0: [VariableAccess] z
|
||||
# 1301| Type = [IntType] int
|
||||
# 1301| ValueCategory = lvalue
|
||||
# 1301| 1: [ConditionalExpr] ... ? ... : ...
|
||||
# 1301| Type = [IntType] int
|
||||
# 1301| ValueCategory = prvalue
|
||||
# 1301| 0: [VariableAccess] b
|
||||
# 1301| Type = [BoolType] bool
|
||||
# 1301| ValueCategory = prvalue(load)
|
||||
# 1301| 1: [VariableAccess] x
|
||||
# 1301| Type = [IntType] int
|
||||
# 1301| ValueCategory = prvalue(load)
|
||||
# 1302| 2: [ExprStmt] ExprStmt
|
||||
# 1302| 0: [AssignExpr] ... = ...
|
||||
# 1302| Type = [IntType] int
|
||||
# 1302| ValueCategory = lvalue
|
||||
# 1302| 0: [VariableAccess] z
|
||||
# 1302| Type = [IntType] int
|
||||
# 1302| ValueCategory = lvalue
|
||||
# 1302| 1: [CStyleCast] (int)...
|
||||
# 1302| Conversion = [IntegralConversion] integral conversion
|
||||
# 1302| Type = [IntType] int
|
||||
# 1302| ValueCategory = prvalue
|
||||
# 1302| expr: [ConditionalExpr] ... ? ... : ...
|
||||
# 1302| Type = [LongType] long
|
||||
# 1302| ValueCategory = prvalue
|
||||
# 1302| 0: [VariableAccess] b
|
||||
# 1302| Type = [BoolType] bool
|
||||
# 1302| ValueCategory = prvalue(load)
|
||||
# 1302| 1: [VariableAccess] y
|
||||
# 1302| Type = [LongType] long
|
||||
# 1302| ValueCategory = prvalue(load)
|
||||
# 1303| 3: [ExprStmt] ExprStmt
|
||||
# 1303| 0: [AssignExpr] ... = ...
|
||||
# 1303| Type = [IntType] int
|
||||
# 1303| ValueCategory = lvalue
|
||||
# 1303| 0: [VariableAccess] z
|
||||
# 1303| Type = [IntType] int
|
||||
# 1303| ValueCategory = lvalue
|
||||
# 1303| 1: [ConditionalExpr] ... ? ... : ...
|
||||
# 1303| Type = [IntType] int
|
||||
# 1303| ValueCategory = prvalue
|
||||
# 1303| 0: [CStyleCast] (bool)...
|
||||
# 1303| Conversion = [BoolConversion] conversion to bool
|
||||
# 1303| Type = [BoolType] bool
|
||||
# 1303| ValueCategory = prvalue
|
||||
# 1303| expr: [VariableAccess] x
|
||||
# 1303| Type = [IntType] int
|
||||
# 1303| ValueCategory = prvalue(load)
|
||||
# 1303| 1: [VariableAccess] x
|
||||
# 1303| Type = [IntType] int
|
||||
# 1303| ValueCategory = prvalue(load)
|
||||
# 1304| 4: [ExprStmt] ExprStmt
|
||||
# 1304| 0: [AssignExpr] ... = ...
|
||||
# 1304| Type = [IntType] int
|
||||
# 1304| ValueCategory = lvalue
|
||||
# 1304| 0: [VariableAccess] z
|
||||
# 1304| Type = [IntType] int
|
||||
# 1304| ValueCategory = lvalue
|
||||
# 1304| 1: [CStyleCast] (int)...
|
||||
# 1304| Conversion = [IntegralConversion] integral conversion
|
||||
# 1304| Type = [IntType] int
|
||||
# 1304| ValueCategory = prvalue
|
||||
# 1304| expr: [ConditionalExpr] ... ? ... : ...
|
||||
# 1304| Type = [LongType] long
|
||||
# 1304| ValueCategory = prvalue
|
||||
# 1304| 0: [CStyleCast] (bool)...
|
||||
# 1304| Conversion = [BoolConversion] conversion to bool
|
||||
# 1304| Type = [BoolType] bool
|
||||
# 1304| ValueCategory = prvalue
|
||||
# 1304| expr: [VariableAccess] x
|
||||
# 1304| Type = [IntType] int
|
||||
# 1304| ValueCategory = prvalue(load)
|
||||
# 1304| 1: [VariableAccess] y
|
||||
# 1304| Type = [LongType] long
|
||||
# 1304| ValueCategory = prvalue(load)
|
||||
# 1305| 5: [ExprStmt] ExprStmt
|
||||
# 1305| 0: [AssignExpr] ... = ...
|
||||
# 1305| Type = [IntType] int
|
||||
# 1305| ValueCategory = lvalue
|
||||
# 1305| 0: [VariableAccess] z
|
||||
# 1305| Type = [IntType] int
|
||||
# 1305| ValueCategory = lvalue
|
||||
# 1305| 1: [CStyleCast] (int)...
|
||||
# 1305| Conversion = [IntegralConversion] integral conversion
|
||||
# 1305| Type = [IntType] int
|
||||
# 1305| ValueCategory = prvalue
|
||||
# 1305| expr: [ConditionalExpr] ... ? ... : ...
|
||||
# 1305| Type = [LongType] long
|
||||
# 1305| ValueCategory = prvalue
|
||||
# 1305| 0: [CStyleCast] (bool)...
|
||||
# 1305| Conversion = [BoolConversion] conversion to bool
|
||||
# 1305| Type = [BoolType] bool
|
||||
# 1305| ValueCategory = prvalue
|
||||
# 1305| expr: [VariableAccess] y
|
||||
# 1305| Type = [LongType] long
|
||||
# 1305| ValueCategory = prvalue(load)
|
||||
# 1305| 1: [CStyleCast] (long)...
|
||||
# 1305| Conversion = [IntegralConversion] integral conversion
|
||||
# 1305| Type = [LongType] long
|
||||
# 1305| ValueCategory = prvalue
|
||||
# 1305| expr: [VariableAccess] x
|
||||
# 1305| Type = [IntType] int
|
||||
# 1305| ValueCategory = prvalue(load)
|
||||
# 1306| 6: [ExprStmt] ExprStmt
|
||||
# 1306| 0: [AssignExpr] ... = ...
|
||||
# 1306| Type = [IntType] int
|
||||
# 1306| ValueCategory = lvalue
|
||||
# 1306| 0: [VariableAccess] z
|
||||
# 1306| Type = [IntType] int
|
||||
# 1306| ValueCategory = lvalue
|
||||
# 1306| 1: [CStyleCast] (int)...
|
||||
# 1306| Conversion = [IntegralConversion] integral conversion
|
||||
# 1306| Type = [IntType] int
|
||||
# 1306| ValueCategory = prvalue
|
||||
# 1306| expr: [ConditionalExpr] ... ? ... : ...
|
||||
# 1306| Type = [LongType] long
|
||||
# 1306| ValueCategory = prvalue
|
||||
# 1306| 0: [CStyleCast] (bool)...
|
||||
# 1306| Conversion = [BoolConversion] conversion to bool
|
||||
# 1306| Type = [BoolType] bool
|
||||
# 1306| ValueCategory = prvalue
|
||||
# 1306| expr: [VariableAccess] y
|
||||
# 1306| Type = [LongType] long
|
||||
# 1306| ValueCategory = prvalue(load)
|
||||
# 1306| 1: [VariableAccess] y
|
||||
# 1306| Type = [LongType] long
|
||||
# 1306| ValueCategory = prvalue(load)
|
||||
# 1308| 7: [ExprStmt] ExprStmt
|
||||
# 1308| 0: [AssignExpr] ... = ...
|
||||
# 1308| Type = [IntType] int
|
||||
# 1308| ValueCategory = lvalue
|
||||
# 1308| 0: [VariableAccess] z
|
||||
# 1308| Type = [IntType] int
|
||||
# 1308| ValueCategory = lvalue
|
||||
# 1308| 1: [ConditionalExpr] ... ? ... : ...
|
||||
# 1308| Type = [IntType] int
|
||||
# 1308| ValueCategory = prvalue
|
||||
# 1308| 0: [ParenthesisExpr] (...)
|
||||
# 1308| Type = [BoolType] bool
|
||||
# 1308| ValueCategory = prvalue
|
||||
# 1308| expr: [LogicalOrExpr] ... || ...
|
||||
# 1308| Type = [BoolType] bool
|
||||
# 1308| ValueCategory = prvalue
|
||||
# 1308| 0: [LogicalAndExpr] ... && ...
|
||||
# 1308| Type = [BoolType] bool
|
||||
# 1308| ValueCategory = prvalue
|
||||
# 1308| 0: [CStyleCast] (bool)...
|
||||
# 1308| Conversion = [BoolConversion] conversion to bool
|
||||
# 1308| Type = [BoolType] bool
|
||||
# 1308| ValueCategory = prvalue
|
||||
# 1308| expr: [VariableAccess] x
|
||||
# 1308| Type = [IntType] int
|
||||
# 1308| ValueCategory = prvalue(load)
|
||||
# 1308| 1: [VariableAccess] b
|
||||
# 1308| Type = [BoolType] bool
|
||||
# 1308| ValueCategory = prvalue(load)
|
||||
# 1308| 1: [CStyleCast] (bool)...
|
||||
# 1308| Conversion = [BoolConversion] conversion to bool
|
||||
# 1308| Type = [BoolType] bool
|
||||
# 1308| ValueCategory = prvalue
|
||||
# 1308| expr: [VariableAccess] y
|
||||
# 1308| Type = [LongType] long
|
||||
# 1308| ValueCategory = prvalue(load)
|
||||
# 1308| 1: [VariableAccess] x
|
||||
# 1308| Type = [IntType] int
|
||||
# 1308| ValueCategory = prvalue(load)
|
||||
# 1309| 8: [ReturnStmt] return ...
|
||||
# 1311| [TopLevelFunction] bool predicateA()
|
||||
# 1311| params:
|
||||
# 1312| [TopLevelFunction] bool predicateB()
|
||||
# 1312| params:
|
||||
# 1314| [TopLevelFunction] int shortCircuitConditional(int, int)
|
||||
# 1314| params:
|
||||
# 1314| 0: [Parameter] x
|
||||
# 1314| Type = [IntType] int
|
||||
# 1314| 1: [Parameter] y
|
||||
# 1314| Type = [IntType] int
|
||||
# 1314| body: [Block] { ... }
|
||||
# 1315| 0: [ReturnStmt] return ...
|
||||
# 1315| 0: [ConditionalExpr] ... ? ... : ...
|
||||
# 1315| Type = [IntType] int
|
||||
# 1315| ValueCategory = prvalue
|
||||
# 1315| 0: [LogicalAndExpr] ... && ...
|
||||
# 1315| Type = [BoolType] bool
|
||||
# 1315| ValueCategory = prvalue
|
||||
# 1315| 0: [FunctionCall] call to predicateA
|
||||
# 1315| Type = [BoolType] bool
|
||||
# 1315| ValueCategory = prvalue
|
||||
# 1315| 1: [FunctionCall] call to predicateB
|
||||
# 1315| Type = [BoolType] bool
|
||||
# 1315| ValueCategory = prvalue
|
||||
# 1315| 1: [VariableAccess] x
|
||||
# 1315| Type = [IntType] int
|
||||
# 1315| ValueCategory = prvalue(load)
|
||||
# 1315| 2: [VariableAccess] y
|
||||
# 1315| Type = [IntType] int
|
||||
# 1315| ValueCategory = prvalue(load)
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| params:
|
||||
|
||||
@@ -1296,4 +1296,23 @@ void returnVoid(int x, int y) {
|
||||
return IntegerOps(x, y);
|
||||
}
|
||||
|
||||
void gccBinaryConditional(bool b, int x, long y) {
|
||||
int z = x;
|
||||
z = b ?: x;
|
||||
z = b ?: y;
|
||||
z = x ?: x;
|
||||
z = x ?: y;
|
||||
z = y ?: x;
|
||||
z = y ?: y;
|
||||
|
||||
z = (x && b || y) ?: x;
|
||||
}
|
||||
|
||||
bool predicateA();
|
||||
bool predicateB();
|
||||
|
||||
int shortCircuitConditional(int x, int y) {
|
||||
return predicateA() && predicateB() ? x : y;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -7258,6 +7258,289 @@ ir.cpp:
|
||||
# 1295| v1295_11(void) = AliasedUse : ~mu1295_4
|
||||
# 1295| v1295_12(void) = ExitFunction :
|
||||
|
||||
# 1299| void gccBinaryConditional(bool, int, long)
|
||||
# 1299| Block 0
|
||||
# 1299| v1299_1(void) = EnterFunction :
|
||||
# 1299| mu1299_2(unknown) = AliasedDefinition :
|
||||
# 1299| mu1299_3(unknown) = InitializeNonLocal :
|
||||
# 1299| mu1299_4(unknown) = UnmodeledDefinition :
|
||||
# 1299| r1299_5(glval<bool>) = VariableAddress[b] :
|
||||
# 1299| mu1299_6(bool) = InitializeParameter[b] : &:r1299_5
|
||||
# 1299| r1299_7(glval<int>) = VariableAddress[x] :
|
||||
# 1299| mu1299_8(int) = InitializeParameter[x] : &:r1299_7
|
||||
# 1299| r1299_9(glval<long>) = VariableAddress[y] :
|
||||
# 1299| mu1299_10(long) = InitializeParameter[y] : &:r1299_9
|
||||
# 1300| r1300_1(glval<int>) = VariableAddress[z] :
|
||||
# 1300| r1300_2(glval<int>) = VariableAddress[x] :
|
||||
# 1300| r1300_3(int) = Load : &:r1300_2, ~mu1299_4
|
||||
# 1300| mu1300_4(int) = Store : &:r1300_1, r1300_3
|
||||
# 1301| r1301_1(glval<bool>) = VariableAddress[b] :
|
||||
# 1301| r1301_2(bool) = Load : &:r1301_1, ~mu1299_4
|
||||
# 1301| v1301_3(void) = ConditionalBranch : r1301_2
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 1301| Block 1
|
||||
# 1301| r1301_4(glval<int>) = VariableAddress[#temp1301:9] :
|
||||
# 1301| r1301_5(int) = Load : &:r1301_4, ~mu1299_4
|
||||
# 1301| r1301_6(glval<int>) = VariableAddress[z] :
|
||||
# 1301| mu1301_7(int) = Store : &:r1301_6, r1301_5
|
||||
# 1302| r1302_1(glval<bool>) = VariableAddress[b] :
|
||||
# 1302| r1302_2(bool) = Load : &:r1302_1, ~mu1299_4
|
||||
# 1302| v1302_3(void) = ConditionalBranch : r1302_2
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 1301| Block 2
|
||||
# 1301| r1301_8(glval<int>) = VariableAddress[#temp1301:9] :
|
||||
# 1301| mu1301_9(int) = Store : &:r1301_8, r1301_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1301| Block 3
|
||||
# 1301| r1301_10(glval<int>) = VariableAddress[x] :
|
||||
# 1301| r1301_11(int) = Load : &:r1301_10, ~mu1299_4
|
||||
# 1301| r1301_12(glval<int>) = VariableAddress[#temp1301:9] :
|
||||
# 1301| mu1301_13(int) = Store : &:r1301_12, r1301_11
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1302| Block 4
|
||||
# 1302| r1302_4(glval<long>) = VariableAddress[#temp1302:9] :
|
||||
# 1302| r1302_5(long) = Load : &:r1302_4, ~mu1299_4
|
||||
# 1302| r1302_6(int) = Convert : r1302_5
|
||||
# 1302| r1302_7(glval<int>) = VariableAddress[z] :
|
||||
# 1302| mu1302_8(int) = Store : &:r1302_7, r1302_6
|
||||
# 1303| r1303_1(glval<int>) = VariableAddress[x] :
|
||||
# 1303| r1303_2(int) = Load : &:r1303_1, ~mu1299_4
|
||||
# 1303| r1303_3(int) = Constant[0] :
|
||||
# 1303| r1303_4(bool) = CompareNE : r1303_2, r1303_3
|
||||
# 1303| v1303_5(void) = ConditionalBranch : r1303_4
|
||||
#-----| False -> Block 9
|
||||
#-----| True -> Block 8
|
||||
|
||||
# 1302| Block 5
|
||||
# 1302| r1302_9(glval<long>) = VariableAddress[#temp1302:9] :
|
||||
# 1302| mu1302_10(long) = Store : &:r1302_9, r1302_2
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 1302| Block 6
|
||||
# 1302| r1302_11(glval<long>) = VariableAddress[y] :
|
||||
# 1302| r1302_12(long) = Load : &:r1302_11, ~mu1299_4
|
||||
# 1302| r1302_13(glval<long>) = VariableAddress[#temp1302:9] :
|
||||
# 1302| mu1302_14(long) = Store : &:r1302_13, r1302_12
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 1303| Block 7
|
||||
# 1303| r1303_6(glval<int>) = VariableAddress[#temp1303:9] :
|
||||
# 1303| r1303_7(int) = Load : &:r1303_6, ~mu1299_4
|
||||
# 1303| r1303_8(glval<int>) = VariableAddress[z] :
|
||||
# 1303| mu1303_9(int) = Store : &:r1303_8, r1303_7
|
||||
# 1304| r1304_1(glval<int>) = VariableAddress[x] :
|
||||
# 1304| r1304_2(int) = Load : &:r1304_1, ~mu1299_4
|
||||
# 1304| r1304_3(int) = Constant[0] :
|
||||
# 1304| r1304_4(bool) = CompareNE : r1304_2, r1304_3
|
||||
# 1304| v1304_5(void) = ConditionalBranch : r1304_4
|
||||
#-----| False -> Block 12
|
||||
#-----| True -> Block 11
|
||||
|
||||
# 1303| Block 8
|
||||
# 1303| r1303_10(glval<int>) = VariableAddress[#temp1303:9] :
|
||||
# 1303| mu1303_11(int) = Store : &:r1303_10, r1303_2
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 1303| Block 9
|
||||
# 1303| r1303_12(glval<int>) = VariableAddress[x] :
|
||||
# 1303| r1303_13(int) = Load : &:r1303_12, ~mu1299_4
|
||||
# 1303| r1303_14(glval<int>) = VariableAddress[#temp1303:9] :
|
||||
# 1303| mu1303_15(int) = Store : &:r1303_14, r1303_13
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 1304| Block 10
|
||||
# 1304| r1304_6(glval<long>) = VariableAddress[#temp1304:9] :
|
||||
# 1304| r1304_7(long) = Load : &:r1304_6, ~mu1299_4
|
||||
# 1304| r1304_8(int) = Convert : r1304_7
|
||||
# 1304| r1304_9(glval<int>) = VariableAddress[z] :
|
||||
# 1304| mu1304_10(int) = Store : &:r1304_9, r1304_8
|
||||
# 1305| r1305_1(glval<long>) = VariableAddress[y] :
|
||||
# 1305| r1305_2(long) = Load : &:r1305_1, ~mu1299_4
|
||||
# 1305| r1305_3(long) = Constant[0] :
|
||||
# 1305| r1305_4(bool) = CompareNE : r1305_2, r1305_3
|
||||
# 1305| v1305_5(void) = ConditionalBranch : r1305_4
|
||||
#-----| False -> Block 15
|
||||
#-----| True -> Block 14
|
||||
|
||||
# 1304| Block 11
|
||||
# 1304| r1304_11(glval<long>) = VariableAddress[#temp1304:9] :
|
||||
# 1304| mu1304_12(long) = Store : &:r1304_11, r1304_2
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 1304| Block 12
|
||||
# 1304| r1304_13(glval<long>) = VariableAddress[y] :
|
||||
# 1304| r1304_14(long) = Load : &:r1304_13, ~mu1299_4
|
||||
# 1304| r1304_15(glval<long>) = VariableAddress[#temp1304:9] :
|
||||
# 1304| mu1304_16(long) = Store : &:r1304_15, r1304_14
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 1305| Block 13
|
||||
# 1305| r1305_6(glval<long>) = VariableAddress[#temp1305:9] :
|
||||
# 1305| r1305_7(long) = Load : &:r1305_6, ~mu1299_4
|
||||
# 1305| r1305_8(int) = Convert : r1305_7
|
||||
# 1305| r1305_9(glval<int>) = VariableAddress[z] :
|
||||
# 1305| mu1305_10(int) = Store : &:r1305_9, r1305_8
|
||||
# 1306| r1306_1(glval<long>) = VariableAddress[y] :
|
||||
# 1306| r1306_2(long) = Load : &:r1306_1, ~mu1299_4
|
||||
# 1306| r1306_3(long) = Constant[0] :
|
||||
# 1306| r1306_4(bool) = CompareNE : r1306_2, r1306_3
|
||||
# 1306| v1306_5(void) = ConditionalBranch : r1306_4
|
||||
#-----| False -> Block 18
|
||||
#-----| True -> Block 17
|
||||
|
||||
# 1305| Block 14
|
||||
# 1305| r1305_11(glval<long>) = VariableAddress[#temp1305:9] :
|
||||
# 1305| mu1305_12(long) = Store : &:r1305_11, r1305_2
|
||||
#-----| Goto -> Block 13
|
||||
|
||||
# 1305| Block 15
|
||||
# 1305| r1305_13(glval<int>) = VariableAddress[x] :
|
||||
# 1305| r1305_14(int) = Load : &:r1305_13, ~mu1299_4
|
||||
# 1305| r1305_15(long) = Convert : r1305_14
|
||||
# 1305| r1305_16(glval<long>) = VariableAddress[#temp1305:9] :
|
||||
# 1305| mu1305_17(long) = Store : &:r1305_16, r1305_15
|
||||
#-----| Goto -> Block 13
|
||||
|
||||
# 1306| Block 16
|
||||
# 1306| r1306_6(glval<long>) = VariableAddress[#temp1306:9] :
|
||||
# 1306| r1306_7(long) = Load : &:r1306_6, ~mu1299_4
|
||||
# 1306| r1306_8(int) = Convert : r1306_7
|
||||
# 1306| r1306_9(glval<int>) = VariableAddress[z] :
|
||||
# 1306| mu1306_10(int) = Store : &:r1306_9, r1306_8
|
||||
# 1308| r1308_1(glval<int>) = VariableAddress[x] :
|
||||
# 1308| r1308_2(int) = Load : &:r1308_1, ~mu1299_4
|
||||
# 1308| r1308_3(int) = Constant[0] :
|
||||
# 1308| r1308_4(bool) = CompareNE : r1308_2, r1308_3
|
||||
# 1308| v1308_5(void) = ConditionalBranch : r1308_4
|
||||
#-----| False -> Block 25
|
||||
#-----| True -> Block 24
|
||||
|
||||
# 1306| Block 17
|
||||
# 1306| r1306_11(glval<long>) = VariableAddress[#temp1306:9] :
|
||||
# 1306| mu1306_12(long) = Store : &:r1306_11, r1306_2
|
||||
#-----| Goto -> Block 16
|
||||
|
||||
# 1306| Block 18
|
||||
# 1306| r1306_13(glval<long>) = VariableAddress[y] :
|
||||
# 1306| r1306_14(long) = Load : &:r1306_13, ~mu1299_4
|
||||
# 1306| r1306_15(glval<long>) = VariableAddress[#temp1306:9] :
|
||||
# 1306| mu1306_16(long) = Store : &:r1306_15, r1306_14
|
||||
#-----| Goto -> Block 16
|
||||
|
||||
# 1308| Block 19
|
||||
# 1308| r1308_6(glval<int>) = VariableAddress[#temp1308:9] :
|
||||
# 1308| r1308_7(int) = Load : &:r1308_6, ~mu1299_4
|
||||
# 1308| r1308_8(glval<int>) = VariableAddress[z] :
|
||||
# 1308| mu1308_9(int) = Store : &:r1308_8, r1308_7
|
||||
# 1309| v1309_1(void) = NoOp :
|
||||
# 1299| v1299_11(void) = ReturnVoid :
|
||||
# 1299| v1299_12(void) = UnmodeledUse : mu*
|
||||
# 1299| v1299_13(void) = AliasedUse : ~mu1299_4
|
||||
# 1299| v1299_14(void) = ExitFunction :
|
||||
|
||||
# 1308| Block 20
|
||||
# 1308| r1308_10(glval<int>) = VariableAddress[#temp1308:9] :
|
||||
# 1308| mu1308_11(int) = Store : &:r1308_10, r1308_16
|
||||
#-----| Goto -> Block 19
|
||||
|
||||
# 1308| Block 21
|
||||
# 1308| r1308_12(glval<bool>) = VariableAddress[#temp1308:10] :
|
||||
# 1308| r1308_13(bool) = Constant[0] :
|
||||
# 1308| mu1308_14(bool) = Store : &:r1308_12, r1308_13
|
||||
#-----| Goto -> Block 22
|
||||
|
||||
# 1308| Block 22
|
||||
# 1308| r1308_15(glval<bool>) = VariableAddress[#temp1308:10] :
|
||||
# 1308| r1308_16(bool) = Load : &:r1308_15, ~mu1299_4
|
||||
# 1308| v1308_17(void) = ConditionalBranch : r1308_16
|
||||
#-----| False -> Block 26
|
||||
#-----| True -> Block 20
|
||||
|
||||
# 1308| Block 23
|
||||
# 1308| r1308_18(glval<bool>) = VariableAddress[#temp1308:10] :
|
||||
# 1308| r1308_19(bool) = Constant[1] :
|
||||
# 1308| mu1308_20(bool) = Store : &:r1308_18, r1308_19
|
||||
#-----| Goto -> Block 22
|
||||
|
||||
# 1308| Block 24
|
||||
# 1308| r1308_21(glval<bool>) = VariableAddress[b] :
|
||||
# 1308| r1308_22(bool) = Load : &:r1308_21, ~mu1299_4
|
||||
# 1308| v1308_23(void) = ConditionalBranch : r1308_22
|
||||
#-----| False -> Block 25
|
||||
#-----| True -> Block 23
|
||||
|
||||
# 1308| Block 25
|
||||
# 1308| r1308_24(glval<long>) = VariableAddress[y] :
|
||||
# 1308| r1308_25(long) = Load : &:r1308_24, ~mu1299_4
|
||||
# 1308| r1308_26(long) = Constant[0] :
|
||||
# 1308| r1308_27(bool) = CompareNE : r1308_25, r1308_26
|
||||
# 1308| v1308_28(void) = ConditionalBranch : r1308_27
|
||||
#-----| False -> Block 21
|
||||
#-----| True -> Block 23
|
||||
|
||||
# 1308| Block 26
|
||||
# 1308| r1308_29(glval<int>) = VariableAddress[x] :
|
||||
# 1308| r1308_30(int) = Load : &:r1308_29, ~mu1299_4
|
||||
# 1308| r1308_31(glval<int>) = VariableAddress[#temp1308:9] :
|
||||
# 1308| mu1308_32(int) = Store : &:r1308_31, r1308_30
|
||||
#-----| Goto -> Block 19
|
||||
|
||||
# 1314| int shortCircuitConditional(int, int)
|
||||
# 1314| Block 0
|
||||
# 1314| v1314_1(void) = EnterFunction :
|
||||
# 1314| mu1314_2(unknown) = AliasedDefinition :
|
||||
# 1314| mu1314_3(unknown) = InitializeNonLocal :
|
||||
# 1314| mu1314_4(unknown) = UnmodeledDefinition :
|
||||
# 1314| r1314_5(glval<int>) = VariableAddress[x] :
|
||||
# 1314| mu1314_6(int) = InitializeParameter[x] : &:r1314_5
|
||||
# 1314| r1314_7(glval<int>) = VariableAddress[y] :
|
||||
# 1314| mu1314_8(int) = InitializeParameter[y] : &:r1314_7
|
||||
# 1315| r1315_1(glval<int>) = VariableAddress[#return] :
|
||||
# 1315| r1315_2(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 1315| r1315_3(bool) = Call : func:r1315_2
|
||||
# 1315| mu1315_4(unknown) = ^CallSideEffect : ~mu1314_4
|
||||
# 1315| v1315_5(void) = ConditionalBranch : r1315_3
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 1315| Block 1
|
||||
# 1315| r1315_6(glval<unknown>) = FunctionAddress[predicateB] :
|
||||
# 1315| r1315_7(bool) = Call : func:r1315_6
|
||||
# 1315| mu1315_8(unknown) = ^CallSideEffect : ~mu1314_4
|
||||
# 1315| v1315_9(void) = ConditionalBranch : r1315_7
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 1315| Block 2
|
||||
# 1315| r1315_10(glval<int>) = VariableAddress[x] :
|
||||
# 1315| r1315_11(int) = Load : &:r1315_10, ~mu1314_4
|
||||
# 1315| r1315_12(glval<int>) = VariableAddress[#temp1315:12] :
|
||||
# 1315| mu1315_13(int) = Store : &:r1315_12, r1315_11
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 1315| Block 3
|
||||
# 1315| r1315_14(glval<int>) = VariableAddress[y] :
|
||||
# 1315| r1315_15(int) = Load : &:r1315_14, ~mu1314_4
|
||||
# 1315| r1315_16(glval<int>) = VariableAddress[#temp1315:12] :
|
||||
# 1315| mu1315_17(int) = Store : &:r1315_16, r1315_15
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 1315| Block 4
|
||||
# 1315| r1315_18(glval<int>) = VariableAddress[#temp1315:12] :
|
||||
# 1315| r1315_19(int) = Load : &:r1315_18, ~mu1314_4
|
||||
# 1315| mu1315_20(int) = Store : &:r1315_1, r1315_19
|
||||
# 1314| r1314_9(glval<int>) = VariableAddress[#return] :
|
||||
# 1314| v1314_10(void) = ReturnValue : &:r1314_9, ~mu1314_4
|
||||
# 1314| v1314_11(void) = UnmodeledUse : mu*
|
||||
# 1314| v1314_12(void) = AliasedUse : ~mu1314_4
|
||||
# 1314| v1314_13(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
Reference in New Issue
Block a user