Skip to content

Commit f6461fe

Browse files
committed
Fix empty if errors on spirv 1.6
1 parent f8f3585 commit f6461fe

File tree

5 files changed

+210
-212
lines changed

5 files changed

+210
-212
lines changed

naga/src/back/spv/block.rs

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,62 +2979,69 @@ impl BlockContext<'_> {
29792979
ref accept,
29802980
ref reject,
29812981
} => {
2982-
let condition_id = self.cached[condition];
2982+
// In spirv 1.6, in a conditional branch the two block ids
2983+
// of the branches can't have the same label. If `accept`
2984+
// and `reject` are both empty (e.g. in `if (condition) {}`)
2985+
// merge id will be both labels. Because both branches are
2986+
// empty, we can skip the if statement.
2987+
if !(accept.is_empty() && reject.is_empty()) {
2988+
let condition_id = self.cached[condition];
2989+
2990+
let merge_id = self.gen_id();
2991+
block.body.push(Instruction::selection_merge(
2992+
merge_id,
2993+
spirv::SelectionControl::NONE,
2994+
));
29832995

2984-
let merge_id = self.gen_id();
2985-
block.body.push(Instruction::selection_merge(
2986-
merge_id,
2987-
spirv::SelectionControl::NONE,
2988-
));
2996+
let accept_id = if accept.is_empty() {
2997+
None
2998+
} else {
2999+
Some(self.gen_id())
3000+
};
3001+
let reject_id = if reject.is_empty() {
3002+
None
3003+
} else {
3004+
Some(self.gen_id())
3005+
};
29893006

2990-
let accept_id = if accept.is_empty() {
2991-
None
2992-
} else {
2993-
Some(self.gen_id())
2994-
};
2995-
let reject_id = if reject.is_empty() {
2996-
None
2997-
} else {
2998-
Some(self.gen_id())
2999-
};
3007+
self.function.consume(
3008+
block,
3009+
Instruction::branch_conditional(
3010+
condition_id,
3011+
accept_id.unwrap_or(merge_id),
3012+
reject_id.unwrap_or(merge_id),
3013+
),
3014+
);
30003015

3001-
self.function.consume(
3002-
block,
3003-
Instruction::branch_conditional(
3004-
condition_id,
3005-
accept_id.unwrap_or(merge_id),
3006-
reject_id.unwrap_or(merge_id),
3007-
),
3008-
);
3016+
if let Some(block_id) = accept_id {
3017+
// We can ignore the `BlockExitDisposition` returned here because,
3018+
// even if `merge_id` is not actually reachable, it is always
3019+
// referred to by the `OpSelectionMerge` instruction we emitted
3020+
// earlier.
3021+
let _ = self.write_block(
3022+
block_id,
3023+
accept,
3024+
BlockExit::Branch { target: merge_id },
3025+
loop_context,
3026+
debug_info,
3027+
)?;
3028+
}
3029+
if let Some(block_id) = reject_id {
3030+
// We can ignore the `BlockExitDisposition` returned here because,
3031+
// even if `merge_id` is not actually reachable, it is always
3032+
// referred to by the `OpSelectionMerge` instruction we emitted
3033+
// earlier.
3034+
let _ = self.write_block(
3035+
block_id,
3036+
reject,
3037+
BlockExit::Branch { target: merge_id },
3038+
loop_context,
3039+
debug_info,
3040+
)?;
3041+
}
30093042

3010-
if let Some(block_id) = accept_id {
3011-
// We can ignore the `BlockExitDisposition` returned here because,
3012-
// even if `merge_id` is not actually reachable, it is always
3013-
// referred to by the `OpSelectionMerge` instruction we emitted
3014-
// earlier.
3015-
let _ = self.write_block(
3016-
block_id,
3017-
accept,
3018-
BlockExit::Branch { target: merge_id },
3019-
loop_context,
3020-
debug_info,
3021-
)?;
3022-
}
3023-
if let Some(block_id) = reject_id {
3024-
// We can ignore the `BlockExitDisposition` returned here because,
3025-
// even if `merge_id` is not actually reachable, it is always
3026-
// referred to by the `OpSelectionMerge` instruction we emitted
3027-
// earlier.
3028-
let _ = self.write_block(
3029-
block_id,
3030-
reject,
3031-
BlockExit::Branch { target: merge_id },
3032-
loop_context,
3033-
debug_info,
3034-
)?;
3043+
block = Block::new(merge_id);
30353044
}
3036-
3037-
block = Block::new(merge_id);
30383045
}
30393046
Statement::Switch {
30403047
selector,

naga/tests/in/wgsl/empty-if.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[spv]
2-
version = [1, 6]
2+
version = [1, 6]

naga/tests/in/wgsl/empty-if.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ fn comp(@builtin(global_invocation_id) id: vec3<u32>) {
44
if (id.x == 0) {
55

66
}
7-
_ = 1+1;
7+
_ = 1+1; // otherwise, naga generates returns in the if statement.
88
return;
99
}

0 commit comments

Comments
 (0)