diff mbox series

tests/tcg/s390x: Fix the exrl-trt* tests with Clang

Message ID 20220301092431.1448419-1-thuth@redhat.com (mailing list archive)
State New, archived
Headers show
Series tests/tcg/s390x: Fix the exrl-trt* tests with Clang | expand

Commit Message

Thomas Huth March 1, 2022, 9:24 a.m. UTC
The exrl-trt* tests use two pre-initialized variables for the
results of the assembly code:

    uint64_t r1 = 0xffffffffffffffffull;
    uint64_t r2 = 0xffffffffffffffffull;

But then the assembly code copies over the full contents
of the register into the output variable, without taking
care of this pre-initialized values:

        "    lgr %[r1],%%r1\n"
        "    lgr %[r2],%%r2\n"

The code then finally compares the register contents to
a value that apparently depends on the pre-initialized values:

    if (r2 != 0xffffffffffffffaaull) {
        write(1, "bad r2\n", 7);
        return 1;
    }

This all works with GCC, since the 0xffffffffffffffff got into
the r2 register there by accident, but it fails completely with
Clang.

Let's fix this by declaring the r1 and r2 variables as proper
register variables instead, so the pre-initialized values get
correctly passed into the inline assembly code.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 tests/tcg/s390x/exrl-trt.c  | 8 +++-----
 tests/tcg/s390x/exrl-trtr.c | 8 +++-----
 2 files changed, 6 insertions(+), 10 deletions(-)

Comments

David Hildenbrand March 1, 2022, 9:44 a.m. UTC | #1
On 01.03.22 10:24, Thomas Huth wrote:
> The exrl-trt* tests use two pre-initialized variables for the
> results of the assembly code:
> 
>     uint64_t r1 = 0xffffffffffffffffull;
>     uint64_t r2 = 0xffffffffffffffffull;
> 
> But then the assembly code copies over the full contents
> of the register into the output variable, without taking
> care of this pre-initialized values:
> 
>         "    lgr %[r1],%%r1\n"
>         "    lgr %[r2],%%r2\n"
> 
> The code then finally compares the register contents to
> a value that apparently depends on the pre-initialized values:
> 
>     if (r2 != 0xffffffffffffffaaull) {
>         write(1, "bad r2\n", 7);
>         return 1;
>     }
> 
> This all works with GCC, since the 0xffffffffffffffff got into
> the r2 register there by accident, but it fails completely with
> Clang.
> 
> Let's fix this by declaring the r1 and r2 variables as proper
> register variables instead, so the pre-initialized values get
> correctly passed into the inline assembly code.
> 
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
>  tests/tcg/s390x/exrl-trt.c  | 8 +++-----
>  tests/tcg/s390x/exrl-trtr.c | 8 +++-----
>  2 files changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/tests/tcg/s390x/exrl-trt.c b/tests/tcg/s390x/exrl-trt.c
> index 16711a3181..451f777b9d 100644
> --- a/tests/tcg/s390x/exrl-trt.c
> +++ b/tests/tcg/s390x/exrl-trt.c
> @@ -5,8 +5,8 @@ int main(void)
>  {
>      char op1[] = "hello";
>      char op2[256];
> -    uint64_t r1 = 0xffffffffffffffffull;
> -    uint64_t r2 = 0xffffffffffffffffull;
> +    register uint64_t r1 asm("r1") = 0xffffffffffffffffull;
> +    register uint64_t r2 asm("r2") = 0xffffffffffffffffull;
>      uint64_t cc;
>      int i;
>  
> @@ -21,8 +21,6 @@ int main(void)
>          "    j 2f\n"
>          "1:  trt 0(1,%[op1]),%[op2]\n"
>          "2:  exrl %[op1_len],1b\n"
> -        "    lgr %[r1],%%r1\n"
> -        "    lgr %[r2],%%r2\n"
>          "    ipm %[cc]\n"
>          : [r1] "+r" (r1),
>            [r2] "+r" (r2),
> @@ -30,7 +28,7 @@ int main(void)
>          : [op1] "a" (&op1),
>            [op1_len] "a" (5),
>            [op2] "Q" (op2)
> -        : "r1", "r2", "cc");
> +        : "cc");
>      cc = (cc >> 28) & 3;
>      if (cc != 2) {
>          write(1, "bad cc\n", 7);
> diff --git a/tests/tcg/s390x/exrl-trtr.c b/tests/tcg/s390x/exrl-trtr.c
> index 5f30cda6bd..422f7f385a 100644
> --- a/tests/tcg/s390x/exrl-trtr.c
> +++ b/tests/tcg/s390x/exrl-trtr.c
> @@ -5,8 +5,8 @@ int main(void)
>  {
>      char op1[] = {0, 1, 2, 3};
>      char op2[256];
> -    uint64_t r1 = 0xffffffffffffffffull;
> -    uint64_t r2 = 0xffffffffffffffffull;
> +    register uint64_t r1 asm("r1") = 0xffffffffffffffffull;
> +    register uint64_t r2 asm("r2") = 0xffffffffffffffffull;
>      uint64_t cc;
>      int i;
>  
> @@ -21,8 +21,6 @@ int main(void)
>          "    j 2f\n"
>          "1:  trtr 3(1,%[op1]),%[op2]\n"
>          "2:  exrl %[op1_len],1b\n"
> -        "    lgr %[r1],%%r1\n"
> -        "    lgr %[r2],%%r2\n"
>          "    ipm %[cc]\n"
>          : [r1] "+r" (r1),
>            [r2] "+r" (r2),
> @@ -30,7 +28,7 @@ int main(void)
>          : [op1] "a" (&op1),
>            [op1_len] "a" (3),
>            [op2] "Q" (op2)
> -        : "r1", "r2", "cc");
> +        : "cc");
>      cc = (cc >> 28) & 3;
>      if (cc != 1) {
>          write(1, "bad cc\n", 7);

Reviewed-by: David Hildenbrand <david@redhat.com>
Richard Henderson March 1, 2022, 6:19 p.m. UTC | #2
On 2/28/22 23:24, Thomas Huth wrote:
> The exrl-trt* tests use two pre-initialized variables for the
> results of the assembly code:
> 
>      uint64_t r1 = 0xffffffffffffffffull;
>      uint64_t r2 = 0xffffffffffffffffull;
> 
> But then the assembly code copies over the full contents
> of the register into the output variable, without taking
> care of this pre-initialized values:
> 
>          "    lgr %[r1],%%r1\n"
>          "    lgr %[r2],%%r2\n"
> 
> The code then finally compares the register contents to
> a value that apparently depends on the pre-initialized values:
> 
>      if (r2 != 0xffffffffffffffaaull) {
>          write(1, "bad r2\n", 7);
>          return 1;
>      }
> 
> This all works with GCC, since the 0xffffffffffffffff got into
> the r2 register there by accident, but it fails completely with
> Clang.
> 
> Let's fix this by declaring the r1 and r2 variables as proper
> register variables instead, so the pre-initialized values get
> correctly passed into the inline assembly code.
> 
> Signed-off-by: Thomas Huth<thuth@redhat.com>
> ---
>   tests/tcg/s390x/exrl-trt.c  | 8 +++-----
>   tests/tcg/s390x/exrl-trtr.c | 8 +++-----
>   2 files changed, 6 insertions(+), 10 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/tests/tcg/s390x/exrl-trt.c b/tests/tcg/s390x/exrl-trt.c
index 16711a3181..451f777b9d 100644
--- a/tests/tcg/s390x/exrl-trt.c
+++ b/tests/tcg/s390x/exrl-trt.c
@@ -5,8 +5,8 @@  int main(void)
 {
     char op1[] = "hello";
     char op2[256];
-    uint64_t r1 = 0xffffffffffffffffull;
-    uint64_t r2 = 0xffffffffffffffffull;
+    register uint64_t r1 asm("r1") = 0xffffffffffffffffull;
+    register uint64_t r2 asm("r2") = 0xffffffffffffffffull;
     uint64_t cc;
     int i;
 
@@ -21,8 +21,6 @@  int main(void)
         "    j 2f\n"
         "1:  trt 0(1,%[op1]),%[op2]\n"
         "2:  exrl %[op1_len],1b\n"
-        "    lgr %[r1],%%r1\n"
-        "    lgr %[r2],%%r2\n"
         "    ipm %[cc]\n"
         : [r1] "+r" (r1),
           [r2] "+r" (r2),
@@ -30,7 +28,7 @@  int main(void)
         : [op1] "a" (&op1),
           [op1_len] "a" (5),
           [op2] "Q" (op2)
-        : "r1", "r2", "cc");
+        : "cc");
     cc = (cc >> 28) & 3;
     if (cc != 2) {
         write(1, "bad cc\n", 7);
diff --git a/tests/tcg/s390x/exrl-trtr.c b/tests/tcg/s390x/exrl-trtr.c
index 5f30cda6bd..422f7f385a 100644
--- a/tests/tcg/s390x/exrl-trtr.c
+++ b/tests/tcg/s390x/exrl-trtr.c
@@ -5,8 +5,8 @@  int main(void)
 {
     char op1[] = {0, 1, 2, 3};
     char op2[256];
-    uint64_t r1 = 0xffffffffffffffffull;
-    uint64_t r2 = 0xffffffffffffffffull;
+    register uint64_t r1 asm("r1") = 0xffffffffffffffffull;
+    register uint64_t r2 asm("r2") = 0xffffffffffffffffull;
     uint64_t cc;
     int i;
 
@@ -21,8 +21,6 @@  int main(void)
         "    j 2f\n"
         "1:  trtr 3(1,%[op1]),%[op2]\n"
         "2:  exrl %[op1_len],1b\n"
-        "    lgr %[r1],%%r1\n"
-        "    lgr %[r2],%%r2\n"
         "    ipm %[cc]\n"
         : [r1] "+r" (r1),
           [r2] "+r" (r2),
@@ -30,7 +28,7 @@  int main(void)
         : [op1] "a" (&op1),
           [op1_len] "a" (3),
           [op2] "Q" (op2)
-        : "r1", "r2", "cc");
+        : "cc");
     cc = (cc >> 28) & 3;
     if (cc != 1) {
         write(1, "bad cc\n", 7);