Skip to content

Commit 1594ceb

Browse files
Simon Camphausenmgehre-amdcferry-AMD
authored
[mlir][EmitC] Fix evaluation order of expressions (llvm#93549)
Expressions with the same precedence were not parenthesized and therefore were possibly evaluated in the wrong order depending on the shape of the expression tree. --------- Co-authored-by: Matthias Gehre <[email protected]> Co-authored-by: Corentin Ferry <[email protected]>
1 parent dc8da7d commit 1594ceb

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,11 @@ LogicalResult CppEmitter::emitOperand(Value value) {
13161316
FailureOr<int> precedence = getOperatorPrecedence(def);
13171317
if (failed(precedence))
13181318
return failure();
1319-
bool encloseInParenthesis = precedence.value() < getExpressionPrecedence();
1319+
1320+
// Sub-expressions with equal or lower precedence need to be parenthesized,
1321+
// as they might be evaluated in the wrong order depending on the shape of
1322+
// the expression tree.
1323+
bool encloseInParenthesis = precedence.value() <= getExpressionPrecedence();
13201324
if (encloseInParenthesis) {
13211325
os << "(";
13221326
pushExpressionPrecedence(lowestPrecedence());

mlir/test/Target/Cpp/expressions.mlir

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ func.func @do_not_inline(%arg0: i32, %arg1: i32, %arg2 : i32) -> i32 {
6565
return %e : i32
6666
}
6767

68-
// CPP-DEFAULT: float paranthesis_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) {
68+
// CPP-DEFAULT: float parentheses_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) {
6969
// CPP-DEFAULT-NEXT: return (float) ([[VAL_1]] + [[VAL_2]] * [[VAL_3]]);
7070
// CPP-DEFAULT-NEXT: }
7171

72-
// CPP-DECLTOP: float paranthesis_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) {
72+
// CPP-DECLTOP: float parentheses_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) {
7373
// CPP-DECLTOP-NEXT: return (float) ([[VAL_1]] + [[VAL_2]] * [[VAL_3]]);
7474
// CPP-DECLTOP-NEXT: }
7575

76-
func.func @paranthesis_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> f32 {
76+
func.func @parentheses_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> f32 {
7777
%e = emitc.expression : f32 {
7878
%a = emitc.add %arg0, %arg1 : (i32, i32) -> i32
7979
%b = emitc.mul %a, %arg2 : (i32, i32) -> i32
@@ -83,6 +83,23 @@ func.func @paranthesis_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) ->
8383
return %e : f32
8484
}
8585

86+
// CPP-DEFAULT: int32_t parentheses_for_same_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) {
87+
// CPP-DEFAULT-NEXT: return [[VAL_3]] / ([[VAL_1]] * [[VAL_2]]);
88+
// CPP-DEFAULT-NEXT: }
89+
90+
// CPP-DECLTOP: int32_t parentheses_for_same_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) {
91+
// CPP-DECLTOP-NEXT: return [[VAL_3]] / ([[VAL_1]] * [[VAL_2]]);
92+
// CPP-DECLTOP-NEXT: }
93+
func.func @parentheses_for_same_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
94+
%e = emitc.expression : i32 {
95+
%0 = emitc.mul %arg0, %arg1 : (i32, i32) -> i32
96+
%1 = emitc.div %arg2, %0 : (i32, i32) -> i32
97+
emitc.yield %1 : i32
98+
}
99+
100+
return %e : i32
101+
}
102+
86103
// CPP-DEFAULT: int32_t multiple_uses(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]], int32_t [[VAL_4:v[0-9]+]]) {
87104
// CPP-DEFAULT-NEXT: bool [[VAL_5:v[0-9]+]] = bar([[VAL_1]] * [[VAL_2]], [[VAL_3]]) - [[VAL_4]] < [[VAL_2]];
88105
// CPP-DEFAULT-NEXT: int32_t [[VAL_6:v[0-9]+]];

0 commit comments

Comments
 (0)