Skip to content

Commit e139df7

Browse files
committed
Update snapshots
1 parent d253dc1 commit e139df7

File tree

3 files changed

+187
-49
lines changed

3 files changed

+187
-49
lines changed

src/codegen/generators/expression_generator.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,17 +681,17 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
681681

682682
if let AstStatement::DirectAccess(_) = member.as_ref().get_stmt() {
683683
let (Some(base), _) = (base, ..) else { panic!() };
684+
let (base, _) = dbg!(collect_base_and_direct_access_for_assignment(&base)).unwrap();
684685
// Step 1
685-
let var = self.annotations.get_qualified_name(base).unwrap();
686-
let error_bits_lvalue =
687-
self.llvm_index.find_loaded_associated_variable_value(var).unwrap();
686+
let value =
687+
self.generate_expression_value(&base)?.get_basic_value_enum().into_pointer_value();
688688

689689
// Step 2
690690
let q_lvalue = self.llvm.builder.build_struct_gep(parameter_struct, index, "").unwrap();
691691

692692
// lhs = lvalue
693693
// rhs = astnode
694-
self.generate_bit_access(error_bits_lvalue, q_lvalue, &assignment, &dt)?;
694+
self.generate_bit_access(value, q_lvalue, &assignment, &dt)?;
695695
};
696696
}
697697

src/codegen/tests/directaccess_test.rs

Lines changed: 103 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -171,44 +171,44 @@ fn temp_output_and_normal_assignments() {
171171
%2 = and i8 %shift, 1
172172
store i8 %2, i8* %1, align 1
173173
call void @FOO(%FOO* %f)
174-
%bbb = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 1
175-
%3 = load i8, i8* %error_bits, align 1
176-
%erase = and i8 %3, -2
177-
%4 = load i8, i8* %bbb, align 1
178-
%value = shl i8 %4, 0
174+
%3 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 1
175+
%4 = load i8, i8* %error_bits, align 1
176+
%erase = and i8 %4, -2
177+
%5 = load i8, i8* %3, align 1
178+
%value = shl i8 %5, 0
179179
%or = or i8 %erase, %value
180180
store i8 %or, i8* %error_bits, align 1
181-
%5 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
181+
%6 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
182182
%load_error_bits1 = load i8, i8* %error_bits, align 1
183183
%shift2 = lshr i8 %load_error_bits1, 0
184-
%6 = and i8 %shift2, 1
185-
store i8 %6, i8* %5, align 1
184+
%7 = and i8 %shift2, 1
185+
store i8 %7, i8* %6, align 1
186186
call void @FOO(%FOO* %f)
187-
%bbb3 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 1
188-
%7 = load i8, i8* %error_bits, align 1
189-
%erase4 = and i8 %7, -2
190-
%8 = load i8, i8* %bbb3, align 1
191-
%value5 = shl i8 %8, 0
192-
%or6 = or i8 %erase4, %value5
193-
store i8 %or6, i8* %error_bits, align 1
194-
%9 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
195-
%load_error_bits7 = load i8, i8* %error_bits, align 1
196-
%shift8 = lshr i8 %load_error_bits7, 0
197-
%10 = and i8 %shift8, 1
198-
store i8 %10, i8* %9, align 1
187+
%8 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 1
188+
%9 = load i8, i8* %error_bits, align 1
189+
%erase3 = and i8 %9, -2
190+
%10 = load i8, i8* %8, align 1
191+
%value4 = shl i8 %10, 0
192+
%or5 = or i8 %erase3, %value4
193+
store i8 %or5, i8* %error_bits, align 1
194+
%11 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
195+
%load_error_bits6 = load i8, i8* %error_bits, align 1
196+
%shift7 = lshr i8 %load_error_bits6, 0
197+
%12 = and i8 %shift7, 1
198+
store i8 %12, i8* %11, align 1
199199
call void @FOO(%FOO* %f)
200-
%bbb9 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 1
201-
%11 = load i8, i8* %error_bits, align 1
202-
%erase10 = and i8 %11, -2
203-
%12 = load i8, i8* %bbb9, align 1
204-
%value11 = shl i8 %12, 0
205-
%or12 = or i8 %erase10, %value11
206-
store i8 %or12, i8* %error_bits, align 1
207-
%13 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
208-
%load_error_bits13 = load i8, i8* %error_bits, align 1
209-
%shift14 = lshr i8 %load_error_bits13, 0
210-
%14 = and i8 %shift14, 1
211-
store i8 %14, i8* %13, align 1
200+
%13 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 1
201+
%14 = load i8, i8* %error_bits, align 1
202+
%erase8 = and i8 %14, -2
203+
%15 = load i8, i8* %13, align 1
204+
%value9 = shl i8 %15, 0
205+
%or10 = or i8 %erase8, %value9
206+
store i8 %or10, i8* %error_bits, align 1
207+
%16 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
208+
%load_error_bits11 = load i8, i8* %error_bits, align 1
209+
%shift12 = lshr i8 %load_error_bits11, 0
210+
%17 = and i8 %shift12, 1
211+
store i8 %17, i8* %16, align 1
212212
call void @FOO(%FOO* %f)
213213
%main_ret = load i32, i32* %main, align 4
214214
ret i32 %main_ret
@@ -223,7 +223,6 @@ fn temp_output_and_normal_assignments() {
223223

224224
// TODO: Add correctness tests
225225
#[test]
226-
#[ignore = "fix me later"]
227226
fn temp_complex_bit_access() {
228227
let ir = codegen(
229228
r"
@@ -247,12 +246,71 @@ fn temp_complex_bit_access() {
247246
f : QUUX;
248247
END_VAR
249248
250-
f(Q => foo.bar.baz.%W3.%X2);
249+
f(Q => foo.bar.baz.%W3);
250+
f(Q => foo.bar.baz.%W3.%B0.%X2);
251251
END_FUNCTION
252252
",
253253
);
254254

255-
assert_snapshot!(ir, @r"");
255+
assert_snapshot!(ir, @r###"
256+
; ModuleID = 'main'
257+
source_filename = "main"
258+
259+
%QUUX = type { i8 }
260+
%foo_struct = type { %bar_struct }
261+
%bar_struct = type { i64 }
262+
263+
@__QUUX__init = unnamed_addr constant %QUUX zeroinitializer
264+
@__foo_struct__init = unnamed_addr constant %foo_struct zeroinitializer
265+
@__bar_struct__init = unnamed_addr constant %bar_struct zeroinitializer
266+
267+
define void @QUUX(%QUUX* %0) section "fn-QUUX:v[u8]" {
268+
entry:
269+
%Q = getelementptr inbounds %QUUX, %QUUX* %0, i32 0, i32 0
270+
ret void
271+
}
272+
273+
define i32 @main() section "fn-main:i32" {
274+
entry:
275+
%main = alloca i32, align 4
276+
%foo = alloca %foo_struct, align 8
277+
%f = alloca %QUUX, align 8
278+
%0 = bitcast %foo_struct* %foo to i8*
279+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 bitcast (%foo_struct* @__foo_struct__init to i8*), i64 ptrtoint (%foo_struct* getelementptr (%foo_struct, %foo_struct* null, i32 1) to i64), i1 false)
280+
%1 = bitcast %QUUX* %f to i8*
281+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %1, i8* align 1 getelementptr inbounds (%QUUX, %QUUX* @__QUUX__init, i32 0, i32 0), i64 ptrtoint (%QUUX* getelementptr (%QUUX, %QUUX* null, i32 1) to i64), i1 false)
282+
store i32 0, i32* %main, align 4
283+
call void @QUUX(%QUUX* %f)
284+
%bar = getelementptr inbounds %foo_struct, %foo_struct* %foo, i32 0, i32 0
285+
%baz = getelementptr inbounds %bar_struct, %bar_struct* %bar, i32 0, i32 0
286+
%2 = getelementptr inbounds %QUUX, %QUUX* %f, i32 0, i32 0
287+
%3 = load i64, i64* %baz, align 4
288+
%erase = and i64 %3, -281474976710657
289+
%4 = load i8, i8* %2, align 1
290+
%5 = zext i8 %4 to i64
291+
%value = shl i64 %5, 48
292+
%or = or i64 %erase, %value
293+
store i64 %or, i64* %baz, align 4
294+
call void @QUUX(%QUUX* %f)
295+
%bar1 = getelementptr inbounds %foo_struct, %foo_struct* %foo, i32 0, i32 0
296+
%baz2 = getelementptr inbounds %bar_struct, %bar_struct* %bar1, i32 0, i32 0
297+
%6 = getelementptr inbounds %QUUX, %QUUX* %f, i32 0, i32 0
298+
%7 = load i64, i64* %baz2, align 4
299+
%erase3 = and i64 %7, -1125899906842625
300+
%8 = load i8, i8* %6, align 1
301+
%9 = zext i8 %8 to i64
302+
%value4 = shl i64 %9, 50
303+
%or5 = or i64 %erase3, %value4
304+
store i64 %or5, i64* %baz2, align 4
305+
%main_ret = load i32, i32* %main, align 4
306+
ret i32 %main_ret
307+
}
308+
309+
; Function Attrs: argmemonly nofree nounwind willreturn
310+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
311+
312+
attributes #0 = { argmemonly nofree nounwind willreturn }
313+
"###);
256314
}
257315

258316
#[test]
@@ -300,11 +358,11 @@ fn temp_explicity() {
300358
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 getelementptr inbounds (%FOO, %FOO* @__FOO__init, i32 0, i32 0), i64 ptrtoint (%FOO* getelementptr (%FOO, %FOO* null, i32 1) to i64), i1 false)
301359
store i32 0, i32* %main, align 4
302360
call void @FOO(%FOO* %f)
303-
%bbb = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
304-
%1 = load i8, i8* %error_bits, align 1
305-
%erase = and i8 %1, -17
306-
%2 = load i8, i8* %bbb, align 1
307-
%value = shl i8 %2, 4
361+
%1 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
362+
%2 = load i8, i8* %error_bits, align 1
363+
%erase = and i8 %2, -17
364+
%3 = load i8, i8* %1, align 1
365+
%value = shl i8 %3, 4
308366
%or = or i8 %erase, %value
309367
store i8 %or, i8* %error_bits, align 1
310368
%main_ret = load i32, i32* %main, align 4
@@ -363,11 +421,11 @@ fn temp_implicit() {
363421
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 getelementptr inbounds (%FOO, %FOO* @__FOO__init, i32 0, i32 0), i64 ptrtoint (%FOO* getelementptr (%FOO, %FOO* null, i32 1) to i64), i1 false)
364422
store i32 0, i32* %main, align 4
365423
call void @FOO(%FOO* %f)
366-
%bbb = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
367-
%1 = load i8, i8* %error_bits, align 1
368-
%erase = and i8 %1, -17
369-
%2 = load i8, i8* %bbb, align 1
370-
%value = shl i8 %2, 4
424+
%1 = getelementptr inbounds %FOO, %FOO* %f, i32 0, i32 0
425+
%2 = load i8, i8* %error_bits, align 1
426+
%erase = and i8 %2, -17
427+
%3 = load i8, i8* %1, align 1
428+
%value = shl i8 %3, 4
371429
%or = or i8 %erase, %value
372430
store i8 %or, i8* %error_bits, align 1
373431
%main_ret = load i32, i32* %main, align 4

tests/correctness/bitaccess.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
22

3+
// TODO: Update tests, variable initialization into program body
4+
35
use crate::*;
46
use pretty_assertions::assert_eq;
57

@@ -214,3 +216,81 @@ fn byteaccess_assignment_should_not_override_current_values() {
214216
let res: i32 = compile_and_run(prog, &mut crate::MainType::default);
215217
assert_eq!(res, 0b0000_0000_1100_0011_1010_1010_0101_0101);
216218
}
219+
220+
// TODO: Add more tests, see [`directaccess_test.rs`] for inspo
221+
#[test]
222+
fn bitaccess_assignment_temp() {
223+
let prog = "
224+
FUNCTION_BLOCK foo
225+
VAR_OUTPUT
226+
OUT_FALSE : BOOL;
227+
OUT_TRUE : BOOL;
228+
END_VAR
229+
230+
OUT_TRUE := TRUE;
231+
OUT_FALSE := FALSE;
232+
END_FUNCTION_BLOCK
233+
234+
FUNCTION main : DINT
235+
VAR
236+
a : BYTE;
237+
END_VAR
238+
239+
VAR_TEMP
240+
foo_instance : foo;
241+
END_VAR
242+
243+
a := 2#1010_1010;
244+
// Invert these ~~bitc-~~bits
245+
foo_instance(OUT_TRUE => a.0);
246+
foo_instance(OUT_TRUE => a.2);
247+
foo_instance(OUT_TRUE => a.4);
248+
foo_instance(OUT_TRUE => a.6);
249+
250+
foo_instance(OUT_FALSE => a.1);
251+
foo_instance(OUT_FALSE => a.3);
252+
foo_instance(OUT_FALSE => a.5);
253+
foo_instance(OUT_FALSE => a.7);
254+
255+
main := a;
256+
END_FUNCTION";
257+
258+
let res: i32 = compile_and_run(prog, &mut crate::MainType::default());
259+
assert_eq!(res, 0b0101_0101);
260+
}
261+
262+
#[test]
263+
fn temppp() {
264+
let prog = "
265+
TYPE foo_struct : STRUCT
266+
bar : bar_struct;
267+
END_STRUCT END_TYPE
268+
269+
TYPE bar_struct : STRUCT
270+
baz : DINT; // 0000_0000_0000_0000_0000_0000_0000_0000
271+
END_STRUCT END_TYPE
272+
273+
FUNCTION_BLOCK QUUX
274+
VAR_OUTPUT
275+
Q : BOOL;
276+
END_VAR
277+
278+
Q := TRUE;
279+
END_FUNCTION_BLOCK
280+
281+
FUNCTION main : DINT
282+
VAR
283+
foo : foo_struct;
284+
f : QUUX;
285+
END_VAR
286+
287+
foo.bar.baz := 0; // ...just to be sure
288+
289+
f(Q => foo.bar.baz.%W1.%B1.%X3); // 0000_1000_0000_0000_0000_0000_0000_0000
290+
main := foo.bar.baz;
291+
END_FUNCTION
292+
";
293+
294+
let res: i32 = compile_and_run(prog, &mut crate::MainType::default());
295+
assert_eq!(res, 0b0000_1000_0000_0000_0000_0000_0000_0000);
296+
}

0 commit comments

Comments
 (0)