aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/torture/pr120122-1.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg/torture/pr120122-1.c')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr120122-1.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr120122-1.c b/gcc/testsuite/gcc.dg/torture/pr120122-1.c
new file mode 100644
index 0000000..dde41d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120122-1.c
@@ -0,0 +1,51 @@
+/* { dg-do run } */
+/* PR tree-optimization/120122 */
+
+#include <stdbool.h>
+
+struct Value {
+ int type;
+ union {
+ bool boolean;
+ long long t;
+ };
+};
+
+static struct Value s_item_mem;
+
+/* truthy was being miscompiled for the value.type==2 case,
+ because we would have a VCE from unsigned char to bool
+ that went from being conditional in the value.type==1 case
+ to unconditional when `value.type!=0`.
+ The move of the VCE from conditional to unconditional,
+ needs to changed into a convert (NOP_EXPR). */
+static bool truthy(void) __attribute__((noipa));
+static bool
+truthy(void)
+{
+ bool tt = false;
+ for(int i = 0; i < 10; i++)
+ {
+ struct Value value = s_item_mem;
+ if (value.type == 0)
+ tt = tt | 0;
+ else if (value.type == 1)
+ tt = tt | value.boolean;
+ else
+ tt = tt | 1;
+ }
+ return tt;
+}
+
+int
+main(void)
+{
+ s_item_mem.type = 2;
+ s_item_mem.t = -1;
+ bool b1 = !truthy();
+ s_item_mem.type = 1;
+ s_item_mem.boolean = b1;
+ bool b = truthy();
+ if (b1 != b) __builtin_abort();
+ if (b) __builtin_abort();
+}