Skip to content

Commit d667f20

Browse files
authored
constant propagation in ranged type limits (#505)
added a test that shows that constants are propagated even in ranged-type's limits, so even if you use (const-)expressions (a+b) to define the limits of a ranged type, the const-expressions will be evaluated during compile time and the result will be used. - as in contrast we would do this calculation all the time at runtime. the behavior was introduced in PR #504 (016328) fixes #350
1 parent 0f37a76 commit d667f20

2 files changed

+70
-0
lines changed

src/codegen/tests/code_gen_tests.rs

+34
Original file line numberDiff line numberDiff line change
@@ -2923,3 +2923,37 @@ fn optional_output_assignment() {
29232923
// codegen should be successful
29242924
insta::assert_snapshot!(result);
29252925
}
2926+
2927+
#[test]
2928+
fn constant_expressions_in_ranged_type_declaration_are_propagated() {
2929+
//GIVEN a ranged type from 0 .. MIN+1 where MIN is a global constant
2930+
//WHEN the code is generated
2931+
let result = codegen(
2932+
"
2933+
VAR_GLOBAL CONSTANT
2934+
MIN : INT := 7;
2935+
END_VAR
2936+
2937+
FUNCTION CheckRangeSigned: INT
2938+
VAR_INPUT
2939+
value : INT;
2940+
lower : INT;
2941+
upper : INT;
2942+
END_VAR
2943+
CheckRangeSigned := value;
2944+
END_FUNCTION
2945+
2946+
PROGRAM prg
2947+
VAR
2948+
x: INT(0 .. MIN+1);
2949+
END_VAR
2950+
x := 5;
2951+
END_PROGRAM",
2952+
);
2953+
2954+
// THEN we expect that the assignment to the range-typed variable (x := 5) will result
2955+
// in a call to CheckRangedSigned where the upper bound is a literal i16 8 - NOT an
2956+
// add-expression that really calculates the upper bound at runtime
2957+
2958+
insta::assert_snapshot!(result);
2959+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
source: src/codegen/tests/code_gen_tests.rs
3+
expression: result
4+
---
5+
; ModuleID = 'main'
6+
source_filename = "main"
7+
8+
%prg_interface = type { i16 }
9+
10+
@MIN = unnamed_addr constant i16 7
11+
@prg_instance = global %prg_interface zeroinitializer
12+
13+
define i16 @CheckRangeSigned(i16 %0, i16 %1, i16 %2) {
14+
entry:
15+
%value = alloca i16, align 2
16+
store i16 %0, i16* %value, align 2
17+
%lower = alloca i16, align 2
18+
store i16 %1, i16* %lower, align 2
19+
%upper = alloca i16, align 2
20+
store i16 %2, i16* %upper, align 2
21+
%CheckRangeSigned = alloca i16, align 2
22+
store i16 0, i16* %CheckRangeSigned, align 2
23+
%load_value = load i16, i16* %value, align 2
24+
store i16 %load_value, i16* %CheckRangeSigned, align 2
25+
%CheckRangeSigned_ret = load i16, i16* %CheckRangeSigned, align 2
26+
ret i16 %CheckRangeSigned_ret
27+
}
28+
29+
define void @prg(%prg_interface* %0) {
30+
entry:
31+
%x = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 0
32+
%call = call i16 @CheckRangeSigned(i16 5, i16 0, i16 8)
33+
store i16 %call, i16* %x, align 2
34+
ret void
35+
}
36+

0 commit comments

Comments
 (0)