aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation/optim
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-06-18 11:49:03 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-06-26 14:01:50 +0200
commit1ed0dfb473629202784f9701991671a6f9c6ff6e (patch)
treea72f796ba6d173eed9ac585363fb41ff097f1b06 /validation/optim
parent4d851248702bebe6c8ecdd1cef54e7782c72b8a2 (diff)
downloadsparse-dev-1ed0dfb473629202784f9701991671a6f9c6ff6e.tar.gz
cast: simplify TRUNC + ZEXT to AND
A truncation followed by a zero-extension to the original size, which is produced when loading a storing bitfields, is equivalent to a simple AND masking. Often, this AND can then trigger even more optimizations. So, replace TRUNC + ZEXT instructions by the equivalent AND. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation/optim')
-rw-r--r--validation/optim/bitfield-init-zero.c102
-rw-r--r--validation/optim/bitfield-size.c44
2 files changed, 146 insertions, 0 deletions
diff --git a/validation/optim/bitfield-init-zero.c b/validation/optim/bitfield-init-zero.c
new file mode 100644
index 00000000..e619d1d2
--- /dev/null
+++ b/validation/optim/bitfield-init-zero.c
@@ -0,0 +1,102 @@
+struct bfu {
+ unsigned int a:11;
+ unsigned int f:9;
+ unsigned int :2;
+ unsigned int z:3;
+};
+
+struct bfu bfuu_init(unsigned int a)
+{
+ struct bfu bf = { .f = a, };
+ return bf;
+}
+
+struct bfu bfus_init(int a)
+{
+ struct bfu bf = { .f = a, };
+ return bf;
+}
+
+unsigned int bfu_get0(void)
+{
+ struct bfu bf = { };
+ return bf.f;
+}
+
+
+struct bfs {
+ signed int a:11;
+ signed int f:9;
+ signed int :2;
+ signed int z:3;
+};
+
+struct bfs bfsu_init(unsigned int a)
+{
+ struct bfs bf = { .f = a, };
+ return bf;
+}
+
+struct bfs bfss_init(int a)
+{
+ struct bfs bf = { .f = a, };
+ return bf;
+}
+
+int bfs_get0(void)
+{
+ struct bfs bf = { };
+ return bf.f;
+}
+
+/*
+ * check-name: bitfield implicit init zero
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+bfuu_init:
+.L0:
+ <entry-point>
+ and.32 %r4 <- %arg1, $511
+ shl.32 %r5 <- %r4, $11
+ ret.32 %r5
+
+
+bfus_init:
+.L2:
+ <entry-point>
+ and.32 %r13 <- %arg1, $511
+ shl.32 %r14 <- %r13, $11
+ ret.32 %r14
+
+
+bfu_get0:
+.L4:
+ <entry-point>
+ ret.32 $0
+
+
+bfsu_init:
+.L6:
+ <entry-point>
+ and.32 %r27 <- %arg1, $511
+ shl.32 %r28 <- %r27, $11
+ ret.32 %r28
+
+
+bfss_init:
+.L8:
+ <entry-point>
+ and.32 %r36 <- %arg1, $511
+ shl.32 %r37 <- %r36, $11
+ ret.32 %r37
+
+
+bfs_get0:
+.L10:
+ <entry-point>
+ ret.32 $0
+
+
+ * check-output-end
+ */
diff --git a/validation/optim/bitfield-size.c b/validation/optim/bitfield-size.c
new file mode 100644
index 00000000..0d2deeea
--- /dev/null
+++ b/validation/optim/bitfield-size.c
@@ -0,0 +1,44 @@
+struct bfu {
+ unsigned int a:4;
+ unsigned int :2;
+ unsigned int b:4;
+};
+unsigned int get__bfu_a(struct bfu bf) { return bf.a; }
+unsigned int get__bfu_b(struct bfu bf) { return bf.b; }
+unsigned int get_pbfu_a(struct bfu *bf) { return bf->a; }
+unsigned int get_pbfu_b(struct bfu *bf) { return bf->b; }
+
+
+struct bfs {
+ signed int a:4;
+ signed int :2;
+ signed int b:4;
+};
+signed int get__bfs_a(struct bfs bf) { return bf.a; }
+signed int get__bfs_b(struct bfs bf) { return bf.b; }
+signed int get_pbfs_a(struct bfs *bf) { return bf->a; }
+signed int get_pbfs_b(struct bfs *bf) { return bf->b; }
+
+
+struct bfi {
+ int a:4;
+ int :2;
+ int b:4;
+};
+unsigned int get__bfi_a(struct bfi bf) { return bf.a; }
+unsigned int get__bfi_b(struct bfi bf) { return bf.b; }
+unsigned int get_pbfi_a(struct bfi *bf) { return bf->a; }
+unsigned int get_pbfi_b(struct bfi *bf) { return bf->b; }
+
+/*
+ * check-name: bitfield size
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: and\\..*\\$960
+ * check-output-excludes: zext\\.
+ * check-output-pattern(8): and\\..*\\$15
+ * check-output-pattern(4): sext\\.
+ * check-output-pattern(4): trunc\\.4
+ * check-output-pattern(6): lsr\\..*\\$6
+ */