+2018-11-20 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * config/s390/s390.md ("clztidi2"): Swap the RTX's written to the
+ DImode parts of the target operand.
+
2018-11-20 Nathan Sidwell <nathan@acm.org>
PR 87926
DONE;
})
+; CLZ result is in hard reg op0 - this is the high part of the target operand
+; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
(define_insn "clztidi2"
[(set (match_operand:TI 0 "register_operand" "=d")
(ior:TI
- (ashift:TI
- (zero_extend:TI
- (xor:DI (match_operand:DI 1 "register_operand" "d")
- (lshiftrt (match_operand:DI 2 "const_int_operand" "")
- (subreg:SI (clz:DI (match_dup 1)) 4))))
-
- (const_int 64))
- (zero_extend:TI (clz:DI (match_dup 1)))))
+ (ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
+ (const_int 64))
+ (zero_extend:TI
+ (xor:DI (match_dup 1)
+ (lshiftrt (match_operand:DI 2 "const_int_operand" "")
+ (subreg:SI (clz:DI (match_dup 1)) 4))))))
(clobber (reg:CC CC_REGNUM))]
"UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
&& TARGET_EXTIMM && TARGET_ZARCH"
+2018-11-20 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * gcc.target/s390/flogr-1.c: New test.
+
2018-11-20 Jan Hubicka <hubicka@ucw.cz>
PR ipa/87706
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -funroll-loops -march=z9-109" } */
+/* { dg-require-effective-target stdint_types } */
+
+/* Folding of the FLOGR caused a wrong value to be returned by
+ __builtin_clz becuase of a problem in the RTX we emit for FLOGR.
+ The problematic folding can only be triggered with constants inputs
+ introduced on RTL level. In this case it happens with loop
+ unrolling. */
+
+#include <stdint.h>
+#include <assert.h>
+
+static inline uint32_t pow2_ceil_u32(uint32_t x) {
+ if (x <= 1) {
+ return x;
+ }
+ int msb_on_index;
+ msb_on_index = (31 ^ __builtin_clz(x - 1));
+ assert(msb_on_index < 31);
+ return 1U << (msb_on_index + 1);
+}
+
+void __attribute__((noinline,noclone))
+die (int a)
+{
+ if (a)
+ __builtin_abort ();
+}
+
+void test_pow2_ceil_u32(void) {
+ unsigned i;
+
+ for (i = 0; i < 18; i++) {
+ uint32_t a_ = (pow2_ceil_u32(((uint32_t)1) << i));
+ if (!(a_ == (((uint32_t)1) << i))) {
+ die(1);
+ }
+ }
+}
+
+int
+main(void) {
+ test_pow2_ceil_u32();
+
+ return 0;
+}