C++: Test demonstrating chi node back edge bug

This test shows that the back-edge detection does not properly account
for chi nodes in the translation to aliased SSA.
This commit is contained in:
Jonas Jensen 2019-01-25 15:28:53 +01:00
Родитель 9963270d63
Коммит 560dbdf984
7 изменённых файлов: 175 добавлений и 0 удалений

Просмотреть файл

@ -6782,3 +6782,47 @@ ir.cpp:
# 1055| 0: i
# 1055| Type = int
# 1055| ValueCategory = prvalue(load)
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
# 1058| params:
# 1058| 0: n
# 1058| Type = int
# 1058| 1: p
# 1058| Type = char *
# 1058| body: { ... }
# 1059| 0: while (...) ...
# 1059| 0: ... > ...
# 1059| Type = bool
# 1059| ValueCategory = prvalue
# 1059| 0: ... --
# 1059| Type = int
# 1059| ValueCategory = prvalue
# 1059| 0: n
# 1059| Type = int
# 1059| ValueCategory = lvalue
# 1059| 1: 0
# 1059| Type = int
# 1059| Value = 0
# 1059| ValueCategory = prvalue
# 1060| 1: ExprStmt
# 1060| 0: ... = ...
# 1060| Type = char
# 1060| ValueCategory = lvalue
# 1060| 0: * ...
# 1060| Type = char
# 1060| ValueCategory = lvalue
# 1060| 0: ... ++
# 1060| Type = char *
# 1060| ValueCategory = prvalue
# 1060| 0: p
# 1060| Type = char *
# 1060| ValueCategory = lvalue
# 1060| 1: (char)...
# 1060| Conversion = integral conversion
# 1060| Type = char
# 1060| Value = 0
# 1060| ValueCategory = prvalue
# 1060| expr: 0
# 1060| Type = int
# 1060| Value = 0
# 1060| ValueCategory = prvalue
# 1061| 1: return ...

Просмотреть файл

@ -4646,3 +4646,46 @@ ir.cpp:
# 1049| Block 2
# 1049| v2_0(void) = Unreached :
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
# 1058| Block 0
# 1058| v0_0(void) = EnterFunction :
# 1058| m0_1(unknown) = AliasedDefinition :
# 1058| mu0_2(unknown) = UnmodeledDefinition :
# 1058| r0_3(glval<int>) = VariableAddress[n] :
# 1058| m0_4(int) = InitializeParameter[n] : r0_3
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
# 1058| m0_6(char *) = InitializeParameter[p] : r0_5
#-----| Goto -> Block 3
# 1060| Block 1
# 1060| r1_0(char) = Constant[0] :
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
# 1060| r1_2(char *) = Load : r1_1, m3_2
# 1060| r1_3(int) = Constant[1] :
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
# 1060| m1_5(char *) = Store : r1_1, r1_4
# 1060| m1_6(char) = Store : r1_2, r1_0
# 1060| m1_7(unknown) = Chi : m3_0, m1_6
#-----| Goto (back edge) -> Block 3
# 1061| Block 2
# 1061| v2_0(void) = NoOp :
# 1058| v2_1(void) = ReturnVoid :
# 1058| v2_2(void) = UnmodeledUse : mu*
# 1058| v2_3(void) = ExitFunction :
# 1059| Block 3
# 1059| m3_0(unknown) = Phi : from 0:m0_1, from 1:m1_7
# 1059| m3_1(int) = Phi : from 0:m0_4, from 1:m3_7
# 1059| m3_2(char *) = Phi : from 0:m0_6, from 1:m1_5
# 1059| r3_3(glval<int>) = VariableAddress[n] :
# 1059| r3_4(int) = Load : r3_3, m3_1
# 1059| r3_5(int) = Constant[1] :
# 1059| r3_6(int) = Sub : r3_4, r3_5
# 1059| m3_7(int) = Store : r3_3, r3_6
# 1059| r3_8(int) = Constant[0] :
# 1059| r3_9(bool) = CompareGT : r3_4, r3_8
# 1059| v3_10(void) = ConditionalBranch : r3_9
#-----| False (back edge) -> Block 2
#-----| True (back edge) -> Block 1

Просмотреть файл

@ -8,4 +8,6 @@ operandAcrossFunctions
instructionWithoutUniqueBlock
containsLoopOfForwardEdges
lostReachability
| ir.cpp:1060:12:1060:12 | Constant: (char)... |
| ir.cpp:1061:1:1061:1 | NoOp: return ... |
backEdgeCountMismatch

Просмотреть файл

@ -1055,4 +1055,9 @@ int DoWhileFalse() {
return i;
}
void chiNodeAtEndOfLoop(int n, char *p) {
while (n-- > 0)
*p++ = 0;
}
// semmle-extractor-options: -std=c++17

Просмотреть файл

@ -4544,3 +4544,42 @@ ir.cpp:
# 1049| v2_5(void) = ReturnValue : r2_4, mu0_2
# 1049| v2_6(void) = UnmodeledUse : mu*
# 1049| v2_7(void) = ExitFunction :
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
# 1058| Block 0
# 1058| v0_0(void) = EnterFunction :
# 1058| mu0_1(unknown) = AliasedDefinition :
# 1058| mu0_2(unknown) = UnmodeledDefinition :
# 1058| r0_3(glval<int>) = VariableAddress[n] :
# 1058| mu0_4(int) = InitializeParameter[n] : r0_3
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
# 1058| mu0_6(char *) = InitializeParameter[p] : r0_5
#-----| Goto -> Block 3
# 1060| Block 1
# 1060| r1_0(char) = Constant[0] :
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
# 1060| r1_2(char *) = Load : r1_1, mu0_2
# 1060| r1_3(int) = Constant[1] :
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
# 1060| mu1_5(char *) = Store : r1_1, r1_4
# 1060| mu1_6(char) = Store : r1_2, r1_0
#-----| Goto (back edge) -> Block 3
# 1061| Block 2
# 1061| v2_0(void) = NoOp :
# 1058| v2_1(void) = ReturnVoid :
# 1058| v2_2(void) = UnmodeledUse : mu*
# 1058| v2_3(void) = ExitFunction :
# 1059| Block 3
# 1059| r3_0(glval<int>) = VariableAddress[n] :
# 1059| r3_1(int) = Load : r3_0, mu0_2
# 1059| r3_2(int) = Constant[1] :
# 1059| r3_3(int) = Sub : r3_1, r3_2
# 1059| mu3_4(int) = Store : r3_0, r3_3
# 1059| r3_5(int) = Constant[0] :
# 1059| r3_6(bool) = CompareGT : r3_1, r3_5
# 1059| v3_7(void) = ConditionalBranch : r3_6
#-----| False -> Block 2
#-----| True -> Block 1

Просмотреть файл

@ -101,6 +101,7 @@
| IR: VirtualMemberFunction | 1 |
| IR: WhileStatements | 4 |
| IR: WhileStmtWithDeclaration | 8 |
| IR: chiNodeAtEndOfLoop | 4 |
| IR: designatedInit | 1 |
| IR: min | 4 |
| IR: operator= | 1 |

Просмотреть файл

@ -4517,3 +4517,44 @@ ir.cpp:
# 1049| Block 2
# 1049| v2_0(void) = Unreached :
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
# 1058| Block 0
# 1058| v0_0(void) = EnterFunction :
# 1058| mu0_1(unknown) = AliasedDefinition :
# 1058| mu0_2(unknown) = UnmodeledDefinition :
# 1058| r0_3(glval<int>) = VariableAddress[n] :
# 1058| m0_4(int) = InitializeParameter[n] : r0_3
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
# 1058| m0_6(char *) = InitializeParameter[p] : r0_5
#-----| Goto -> Block 3
# 1060| Block 1
# 1060| r1_0(char) = Constant[0] :
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
# 1060| r1_2(char *) = Load : r1_1, m3_1
# 1060| r1_3(int) = Constant[1] :
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
# 1060| m1_5(char *) = Store : r1_1, r1_4
# 1060| mu1_6(char) = Store : r1_2, r1_0
#-----| Goto (back edge) -> Block 3
# 1061| Block 2
# 1061| v2_0(void) = NoOp :
# 1058| v2_1(void) = ReturnVoid :
# 1058| v2_2(void) = UnmodeledUse : mu*
# 1058| v2_3(void) = ExitFunction :
# 1059| Block 3
# 1059| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6
# 1059| m3_1(char *) = Phi : from 0:m0_6, from 1:m1_5
# 1059| r3_2(glval<int>) = VariableAddress[n] :
# 1059| r3_3(int) = Load : r3_2, m3_0
# 1059| r3_4(int) = Constant[1] :
# 1059| r3_5(int) = Sub : r3_3, r3_4
# 1059| m3_6(int) = Store : r3_2, r3_5
# 1059| r3_7(int) = Constant[0] :
# 1059| r3_8(bool) = CompareGT : r3_3, r3_7
# 1059| v3_9(void) = ConditionalBranch : r3_8
#-----| False -> Block 2
#-----| True -> Block 1