Skip to content

Commit 3af9fd3

Browse files
committed
fix: simplify && and || when the LHS is constant
To fix #2946, we can precompute the LHS and allow one of the existing optimizations to generate an `if` that gets precomputed later. Still, for slightly more complicated cases, like `123 && 456`, that alone doesn't seem to work. So we add an additional optimization to check the truthiness of the LHS and use that to simplify the expression to either the LHS or the RHS, without generating an `if`.
1 parent 9664c5b commit 3af9fd3

File tree

4 files changed

+56
-233
lines changed

4 files changed

+56
-233
lines changed

src/compiler.ts

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4574,16 +4574,30 @@ export class Compiler extends DiagnosticEmitter {
45744574
}
45754575
leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);
45764576
leftType = commonType;
4577+
4578+
// This is sometimes needed to make the left trivial
4579+
let leftPrecompExpr = module.runExpression(leftExpr, ExpressionRunnerFlags.PreserveSideeffects);
4580+
if (leftPrecompExpr) leftExpr = leftPrecompExpr;
4581+
45774582
rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);
45784583
rightType = commonType;
45794584

45804585
// simplify if copying left is trivial
45814586
if (expr = module.tryCopyTrivialExpression(leftExpr)) {
4582-
expr = module.if(
4583-
this.makeIsTrueish(leftExpr, this.currentType, left),
4584-
rightExpr,
4585-
expr
4586-
);
4587+
let condExpr = this.makeIsTrueish(leftExpr, this.currentType, left);
4588+
let condKind = this.evaluateCondition(condExpr);
4589+
4590+
if (condKind == ConditionKind.Unknown) {
4591+
expr = module.if(
4592+
condExpr,
4593+
rightExpr,
4594+
expr
4595+
);
4596+
} else {
4597+
expr = condKind == ConditionKind.True
4598+
? rightExpr
4599+
: expr;
4600+
}
45874601

45884602
// if not possible, tee left to a temp
45894603
} else {
@@ -4654,16 +4668,30 @@ export class Compiler extends DiagnosticEmitter {
46544668
let possiblyNull = leftType.is(TypeFlags.Nullable) && rightType.is(TypeFlags.Nullable);
46554669
leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);
46564670
leftType = commonType;
4671+
4672+
// This is sometimes needed to make the left trivial
4673+
let leftPrecompExpr = module.runExpression(leftExpr, ExpressionRunnerFlags.PreserveSideeffects);
4674+
if (leftPrecompExpr) leftExpr = leftPrecompExpr;
4675+
46574676
rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);
46584677
rightType = commonType;
46594678

46604679
// simplify if copying left is trivial
46614680
if (expr = module.tryCopyTrivialExpression(leftExpr)) {
4662-
expr = module.if(
4663-
this.makeIsTrueish(leftExpr, leftType, left),
4664-
expr,
4665-
rightExpr
4666-
);
4681+
let condExpr = this.makeIsTrueish(leftExpr, this.currentType, left);
4682+
let condKind = this.evaluateCondition(condExpr);
4683+
4684+
if (condKind == ConditionKind.Unknown) {
4685+
expr = module.if(
4686+
condExpr,
4687+
expr,
4688+
rightExpr
4689+
);
4690+
} else {
4691+
expr = condKind == ConditionKind.True
4692+
? expr
4693+
: rightExpr;
4694+
}
46674695

46684696
// if not possible, tee left to a temp. local
46694697
} else {

0 commit comments

Comments
 (0)