Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR][CodeGen] Handling multiple stmt followed after a switch case #878

Merged
merged 1 commit into from
Sep 24, 2024

Conversation

ChuanqiXu9
Copy link
Member

Close #876

We've already considered the case that there are random stmt after a switch case:

for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}

However, maybe this is an oversight, in the branch of if (lastCaseBlock), the insertion point will be updated automatically when the RAII object guardCase destroys, then we can assign the correct value for lastCaseBlock later. So we will see the weird code pattern in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with the ones other code gen places. Is this intentional? And what is the motivation and guide lines here?

@ChuanqiXu9 ChuanqiXu9 requested review from gitoleg, bcardosolopes and lanza and removed request for bcardosolopes and lanza September 24, 2024 06:10
@bcardosolopes
Copy link
Member

Thanks for fixing this, awesome!

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with the ones other code gen places. Is this intentional? And what is the motivation and guide lines here?

Structured control flow diverges a bit from the basic block dance of OG, so this ends up being a bit different. Some of it might have been due to some technical debt from early project days too. If you want to refactor it to make it more like OG that's also a welcome change, but I won't ask you to do that as a prereq, thanks for fixing this.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bcardosolopes bcardosolopes changed the title [CIR] [CodeGen] Handling multiple stmt followed after a switch case [CIR][CodeGen] Handling multiple stmt followed after a switch case Sep 24, 2024
@bcardosolopes bcardosolopes merged commit 72b42af into llvm:main Sep 24, 2024
7 checks passed
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
…lvm#878)

Close llvm#876

We've already considered the case that there are random stmt after a
switch case:

```
for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}
```

However, maybe this is an oversight, in the branch of ` if
(lastCaseBlock)`, the insertion point will be updated automatically when
the RAII object `guardCase` destroys, then we can assign the correct
value for `lastCaseBlock` later. So we will see the weird code pattern
in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with
the ones other code gen places. Is this intentional? And what is the
motivation and guide lines here?
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…lvm#878)

Close llvm#876

We've already considered the case that there are random stmt after a
switch case:

```
for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}
```

However, maybe this is an oversight, in the branch of ` if
(lastCaseBlock)`, the insertion point will be updated automatically when
the RAII object `guardCase` destroys, then we can assign the correct
value for `lastCaseBlock` later. So we will see the weird code pattern
in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with
the ones other code gen places. Is this intentional? And what is the
motivation and guide lines here?
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…lvm#878)

Close llvm#876

We've already considered the case that there are random stmt after a
switch case:

```
for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}
```

However, maybe this is an oversight, in the branch of ` if
(lastCaseBlock)`, the insertion point will be updated automatically when
the RAII object `guardCase` destroys, then we can assign the correct
value for `lastCaseBlock` later. So we will see the weird code pattern
in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with
the ones other code gen places. Is this intentional? And what is the
motivation and guide lines here?
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…lvm#878)

Close llvm#876

We've already considered the case that there are random stmt after a
switch case:

```
for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}
```

However, maybe this is an oversight, in the branch of ` if
(lastCaseBlock)`, the insertion point will be updated automatically when
the RAII object `guardCase` destroys, then we can assign the correct
value for `lastCaseBlock` later. So we will see the weird code pattern
in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with
the ones other code gen places. Is this intentional? And what is the
motivation and guide lines here?
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
…lvm#878)

Close llvm#876

We've already considered the case that there are random stmt after a
switch case:

```
for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}
```

However, maybe this is an oversight, in the branch of ` if
(lastCaseBlock)`, the insertion point will be updated automatically when
the RAII object `guardCase` destroys, then we can assign the correct
value for `lastCaseBlock` later. So we will see the weird code pattern
in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with
the ones other code gen places. Is this intentional? And what is the
motivation and guide lines here?
lanza pushed a commit that referenced this pull request Nov 5, 2024
)

Close #876

We've already considered the case that there are random stmt after a
switch case:

```
for (auto *c : compoundStmt->body()) {
      if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
        res = buildSwitchCase(*switchCase, condType, caseAttrs);
      } else if (lastCaseBlock) {
        // This means it's a random stmt following up a case, just
        // emit it as part of previous known case.
        mlir::OpBuilder::InsertionGuard guardCase(builder);
        builder.setInsertionPointToEnd(lastCaseBlock);
        res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
      } else {
        llvm_unreachable("statement doesn't belong to any case region, NYI");
      }

      lastCaseBlock = builder.getBlock();

      if (res.failed())
        break;
}
```

However, maybe this is an oversight, in the branch of ` if
(lastCaseBlock)`, the insertion point will be updated automatically when
the RAII object `guardCase` destroys, then we can assign the correct
value for `lastCaseBlock` later. So we will see the weird code pattern
in the issue side.

BTW, I found the codes in CIRGenStmt.cpp are far more less similar with
the ones other code gen places. Is this intentional? And what is the
motivation and guide lines here?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crash with label with break in a switch case
2 participants