1  /* { dg-do compile } */
       2  /* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
       3  /* { dg-do run { target { s390_z14_hw } } } */
       4  #include <assert.h>
       5  #include <stdint.h>
       6  
       7  __attribute__ ((noipa)) static long double
       8  sqxbr (long double x)
       9  {
      10    register long double in asm("f0") = x;
      11    register long double out asm("f1");
      12  
      13    asm("sqxbr\t%0,%1" : "=f"(out) : "f"(in));
      14    asm("# %0" : "+f"(out));
      15  
      16    return out;
      17  }
      18  
      19  /* Ideally `vmrlg %v3,%v1,%v3` should be optimized away, but the compiler
      20   * can't do it, because the UNSPEC pattern operates on the whole register.
      21   * Using the SUBREG pattern solves this problem, but it's fragile.
      22   */
      23  /* { dg-final { scan-assembler-times {\n\tvmrlg\t%v2,%v0,%v2\n} 1 } } */
      24  /* { dg-final { scan-assembler-times {\n\tvmrhg\t%v1,%v1,%v3\n} 2 } } */
      25  /* { dg-final { scan-assembler-times {\n\tvmrlg\t%v3,%v1,%v3\n} 1 } } */
      26  
      27  int
      28  main (void)
      29  {
      30    long double x = 0x1.0000000000001p+0L,
      31  	      exp = 1.00000000000000011102230246251564788e+0L;
      32    assert (sqxbr (x) == exp);
      33  }