diff --git a/src/Expr.h b/src/Expr.h index 73929a2114..c03bf4a76f 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -474,7 +474,16 @@ public: // Optimization-related: ExprPtr Duplicate() override; - ValPtr FoldVal() const override { return val; } + + ValPtr FoldVal() const override { + if ( type->Tag() == TYPE_OPAQUE ) + // Aggressive constant propagation can lead to the appearance of + // opaque "constants". Don't consider these as foldable because + // they're problematic to generate independently. + return nullptr; + + return val; + } protected: void ExprDescribe(ODesc* d) const override; diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index b727171ee3..84e70e6543 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -475,7 +475,8 @@ ExprPtr UnaryExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { auto op_val = op->FoldVal(); if ( op_val ) { auto fold = Fold(op_val.get()); - return TransformMe(make_intrusive(fold), c, red_stmt); + if ( fold->GetType()->Tag() != TYPE_OPAQUE ) + return TransformMe(make_intrusive(fold), c, red_stmt); } if ( c->Optimizing() ) @@ -523,7 +524,8 @@ ExprPtr BinaryExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { auto op2_fold_val = op2->FoldVal(); if ( op1_fold_val && op2_fold_val ) { auto fold = Fold(op1_fold_val.get(), op2_fold_val.get()); - return TransformMe(make_intrusive(fold), c, red_stmt); + if ( fold->GetType()->Tag() != TYPE_OPAQUE ) + return TransformMe(make_intrusive(fold), c, red_stmt); } if ( c->Optimizing() )