@@ -12611,6 +12611,7 @@ restart:
{
case MULT_EXPR:
case TRUNC_DIV_EXPR:
+ case RDIV_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case LSHIFT_EXPR:
@@ -29835,6 +29835,7 @@ restart:
{
case MULT_EXPR:
case TRUNC_DIV_EXPR:
+ case RDIV_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case LSHIFT_EXPR:
@@ -206,6 +206,9 @@ c_finish_omp_atomic (location_t loc, enu
return error_mark_node;
}
+ if (opcode == RDIV_EXPR)
+ opcode = TRUNC_DIV_EXPR;
+
/* ??? Validate that rhs does not overlap lhs. */
/* Take and save the address of the lhs. From then on we'll reference it
@@ -240,7 +243,7 @@ c_finish_omp_atomic (location_t loc, enu
to do this, and then take it apart again. */
if (swapped)
{
- rhs = build2_loc (loc, opcode, TREE_TYPE (lhs), rhs, lhs);
+ rhs = build_binary_op (loc, opcode, rhs, lhs, 1);
opcode = NOP_EXPR;
}
bool save = in_late_binary_op;
@@ -0,0 +1,16 @@
+/* PR c/64824 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp" } */
+
+int
+main ()
+{
+ long long a;
+ long long b = 1LL;
+ int c = 3;
+#pragma omp atomic capture
+ a = b = c << b;
+ if (b != 6LL || a != 6LL)
+ __builtin_abort ();
+ return 0;
+}
@@ -0,0 +1,87 @@
+/* PR c/64868 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp" } */
+
+float f = 2.0f;
+double d = 4.0;
+long double ld = 8.0L;
+
+void
+foo ()
+{
+#pragma omp atomic
+ f = 1.0f / f;
+#pragma omp atomic
+ f = 1 / f;
+#pragma omp atomic
+ f = f / 2.0f;
+#pragma omp atomic
+ f = f / 2;
+#pragma omp atomic
+ f /= 2.0f;
+#pragma omp atomic
+ f /= 2;
+#pragma omp atomic
+ d = 1.0 / d;
+#pragma omp atomic
+ d = 1 / d;
+#pragma omp atomic
+ d = d / 2.0;
+#pragma omp atomic
+ d = d / 2;
+#pragma omp atomic
+ d /= 2.0;
+#pragma omp atomic
+ d /= 2;
+#pragma omp atomic
+ ld = 1.0L / ld;
+#pragma omp atomic
+ ld = 1 / ld;
+#pragma omp atomic
+ ld = ld / 2.0L;
+#pragma omp atomic
+ ld = ld / 2;
+#pragma omp atomic
+ ld /= 2.0L;
+#pragma omp atomic
+ ld /= 2;
+ if (f != 0.125f || d != 0.25 || ld != 0.5L)
+ __builtin_abort ();
+}
+
+#ifdef __cplusplus
+template <typename T, int N1, int N2>
+void
+bar ()
+{
+ T v = ::d;
+#pragma omp atomic
+ v *= 16;
+#pragma omp atomic
+ v = 1.0 / v;
+#pragma omp atomic
+ v = N1 / v;
+#pragma omp atomic
+ v = v / 2.0;
+#pragma omp atomic
+ v = v / N2;
+#pragma omp atomic
+ v /= 2.0;
+#pragma omp atomic
+ v /= N2;
+ if (v != 0.25)
+ __builtin_abort ();
+}
+#endif
+
+int
+main ()
+{
+ foo ();
+#ifdef __cplusplus
+ bar<float, 1, 2> ();
+ bar<double, 1, 2> ();
+ bar<long double, 1, 2> ();
+#endif
+ return 0;
+}
@@ -0,0 +1,5 @@
+// PR c/64824
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/pr64824.c"
@@ -0,0 +1,5 @@
+// PR c/64868
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/pr64868.c"