Skip to content

Commit daee4a4

Browse files
committed
Put post-conditional assignments in a separate block
1 parent e12f113 commit daee4a4

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

src/strands/strands_conditionals.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ function buildConditional(strandsContext, conditional) {
4141
const mergeBlock = CFG.createBasicBlock(cfg, BlockType.MERGE);
4242
const results = [];
4343
const branchBlocks = [];
44+
const branchEndBlocks = [];
4445
const mergedAssignments = {};
4546
const phiBlockDependencies = {};
4647
// Create a BRANCH block to handle phi node declarations
@@ -64,27 +65,28 @@ function buildConditional(strandsContext, conditional) {
6465
}
6566
const scopeStartBlock = CFG.createBasicBlock(cfg, BlockType.SCOPE_START);
6667
CFG.addEdge(cfg, previousBlock, scopeStartBlock);
67-
const branchBlock = CFG.createBasicBlock(cfg, blockType);
68-
CFG.addEdge(cfg, scopeStartBlock, branchBlock);
69-
branchBlocks.push(branchBlock);
70-
CFG.pushBlock(cfg, branchBlock);
68+
const branchContentBlock = CFG.createBasicBlock(cfg, blockType);
69+
CFG.addEdge(cfg, scopeStartBlock, branchContentBlock);
70+
branchBlocks.push(branchContentBlock);
71+
CFG.pushBlock(cfg, branchContentBlock);
7172
const branchResults = branchCallback();
7273
for (const key in branchResults) {
7374
if (!phiBlockDependencies[key]) {
74-
phiBlockDependencies[key] = [{ value: branchResults[key], blockId: branchBlock }];
75+
phiBlockDependencies[key] = [{ value: branchResults[key], blockId: branchContentBlock }];
7576
} else {
76-
phiBlockDependencies[key].push({ value: branchResults[key], blockId: branchBlock });
77+
phiBlockDependencies[key].push({ value: branchResults[key], blockId: branchContentBlock });
7778
}
7879
}
7980
results.push(branchResults);
81+
82+
// Create BRANCH_END block for phi assignments
83+
const branchEndBlock = CFG.createBasicBlock(cfg, BlockType.DEFAULT);
84+
CFG.addEdge(cfg, cfg.currentBlock, branchEndBlock);
85+
branchEndBlocks.push(branchEndBlock);
86+
CFG.popBlock(cfg);
87+
8088
const scopeEndBlock = CFG.createBasicBlock(cfg, BlockType.SCOPE_END);
81-
if (cfg.currentBlock !== branchBlock) {
82-
CFG.addEdge(cfg, cfg.currentBlock, scopeEndBlock);
83-
CFG.popBlock(cfg);
84-
} else {
85-
CFG.addEdge(cfg, branchBlock, scopeEndBlock);
86-
CFG.popBlock(cfg);
87-
}
89+
CFG.addEdge(cfg, branchEndBlock, scopeEndBlock);
8890
CFG.addEdge(cfg, scopeEndBlock, mergeBlock);
8991
previousBlock = scopeStartBlock;
9092
}
@@ -96,8 +98,8 @@ function buildConditional(strandsContext, conditional) {
9698
CFG.popBlock(cfg);
9799
for (let i = 0; i < results.length; i++) {
98100
const branchResult = results[i];
99-
const branchBlockID = branchBlocks[i];
100-
CFG.pushBlockForModification(cfg, branchBlockID);
101+
const branchEndBlockID = branchEndBlocks[i];
102+
CFG.pushBlockForModification(cfg, branchEndBlockID);
101103
for (const key in branchResult) {
102104
if (mergedAssignments[key]) {
103105
// Create an assignment statement: phiNode = branchResult[key]
@@ -112,7 +114,7 @@ function buildConditional(strandsContext, conditional) {
112114
phiBlocks: []
113115
};
114116
const assignmentID = DAG.getOrCreateNode(strandsContext.dag, assignmentNode);
115-
CFG.recordInBasicBlock(cfg, branchBlockID, assignmentID);
117+
CFG.recordInBasicBlock(cfg, branchEndBlockID, assignmentID);
116118
}
117119
}
118120
CFG.popBlock(cfg);

test/unit/webgl/p5.Shader.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,32 @@ suite('p5.Shader', function() {
596596
assert.approximately(pixelColor[1], 127, 5); // Green channel should be ~127
597597
assert.approximately(pixelColor[2], 127, 5); // Blue channel should be ~127
598598
});
599+
test('handle if-else-if chains in the else branch', () => {
600+
myp5.createCanvas(50, 50, myp5.WEBGL);
601+
const testShader = myp5.baseMaterialShader().modify(() => {
602+
const value = myp5.uniformFloat(() => 0.2); // middle value
603+
myp5.getPixelInputs(inputs => {
604+
let color = myp5.float(0.0);
605+
if (value > 0.8) {
606+
color = myp5.float(1.0); // white for high values
607+
} else if (value > 0.3) {
608+
color = myp5.float(0.5); // gray for medium values
609+
} else {
610+
color = myp5.float(0.0); // black for low values
611+
}
612+
inputs.color = [color, color, color, 1.0];
613+
return inputs;
614+
});
615+
}, { myp5 });
616+
myp5.noStroke();
617+
myp5.shader(testShader);
618+
myp5.plane(myp5.width, myp5.height);
619+
// Check that the center pixel is gray (medium condition was true)
620+
const pixelColor = myp5.get(25, 25);
621+
assert.approximately(pixelColor[0], 0, 5); // Red channel should be ~127 (gray)
622+
assert.approximately(pixelColor[1], 0, 5); // Green channel should be ~127
623+
assert.approximately(pixelColor[2], 0, 5); // Blue channel should be ~127
624+
});
599625
test('handle nested if statements', () => {
600626
myp5.createCanvas(50, 50, myp5.WEBGL);
601627
const testShader = myp5.baseMaterialShader().modify(() => {

0 commit comments

Comments
 (0)