Bug 438038

Summary: Addition of arm64 v8.2 FCCMP, FCCMPE, FCMEQ, FCMGE and FCMGT instructions
Product: [Developer tools] valgrind Reporter: ahashmi <assad.hashmi>
Component: vexAssignee: ahashmi <assad.hashmi>
Status: CLOSED FIXED    
Severity: normal CC: jseward
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Adds arm64 v8.2 FCCMP, FCCMPE, FCMEQ, FCMGE and FCMGT instructions
Adds arm64 v8.2 FCCMP, FCCMPE, FCMEQ, FCMGE and FCMGT instructions

Description ahashmi 2021-06-03 14:20:03 UTC
This patch is part of work adding arm64 v8.2 support as summarised in container bug https://bugs.kde.org/show_bug.cgi?id=428016
Comment 1 ahashmi 2021-06-11 14:07:49 UTC
Created attachment 139231 [details]
Adds arm64 v8.2 FCCMP, FCCMPE, FCMEQ, FCMGE and FCMGT instructions

Note to reviewers: this patch may look a bit big at first glance but there's a lot of boilerplate test code and fairly straightforward IR construction additions.

Patch has been tested with --memcheck:leak-check=yes --tool=memcheck --track-origins=yes
Comment 2 ahashmi 2021-06-14 16:49:56 UTC
Compare-with-zero variants of these instructions are implemented by https://bugs.kde.org/show_bug.cgi?id=438630
Comment 3 Julian Seward 2021-06-17 12:39:25 UTC
(In reply to ahashmi from comment #1)
> Created attachment 139231 [details]
> Adds arm64 v8.2 FCCMP, FCCMPE, FCMEQ, FCMGE and FCMGT instructions

Looks mostly fine.  Comments below.  
r+ provided the SIGILL-vs-assert thing is fixed.


In dis_AdvSIMD_fp_conditional_compare

+   else if (ty == 3) {
+      if ((archinfo->hwcaps & VEX_HWCAPS_ARM64_FP16) == 0)
+         return False;
+      ity  = Ity_F16;
+      irop = Iop_CmpF16;
+   }
+   else
+      vassert(0); /* ty = 2 => illegal encoding */

No .. ensure SIGILL is raised (decode failure) for any undecodable insns.
Never assert.


+   setFlags_COPY(nzcv_28x0);
+   DIP("fccmp%s %s, %s, #%u, %s\n", isCMPE ? "e" : "",
+       nameQRegLO(nn, ity), nameQRegLO(mm, ity), nzcv, nameCC(cond));
+   return True;
 
    return False;

This is a strange sequence.  The second return is unreachable.  (Maybe I
misread?)


+      if (e->Iex.Binop.op == Iop_CmpF64 || e->Iex.Binop.op == Iop_CmpF32 ||
+          e->Iex.Binop.op == Iop_CmpF16) {
+         HReg (*iselExpr)(ISelEnv*, IRExpr*);
+         ARM64Instr* (*VCmp)(HReg, HReg);

As a nit, in such situations I'd prefer if you set these both to NULL so as to
protect against future snafus .. I know it's redundant as the code stands.
Viz:

         HReg (*iselExpr)(ISelEnv*, IRExpr*) = NULL;
         ARM64Instr* (*VCmp)(HReg, HReg) = NULL;
Comment 4 ahashmi 2021-06-29 10:22:56 UTC
Created attachment 139733 [details]
Adds arm64 v8.2 FCCMP, FCCMPE, FCMEQ, FCMGE and FCMGT instructions

Updated patch to address issues raised by review.
Comment 5 ahashmi 2021-06-29 10:27:59 UTC
(In reply to Julian Seward from comment #3)

> No .. ensure SIGILL is raised (decode failure) for any undecodable insns.
> Never assert.
Good point, I've changed it to:
+ else {
+    /* ty = 2 is an illegal encoding */
+    if (sigill_diag) {
+       vex_printf("ARM64 front end: dis_AdvSIMD_fp_conditional_compare\n");
+    }
+    return False;
+ }


> +   return True;
>  
>     return False;
> 
> This is a strange sequence.  The second return is unreachable.  (Maybe I
> misread?)
My bad. The second return is a leftover from some debug testing which I should have deleted.


> As a nit, in such situations I'd prefer if you set these both to NULL so as to
> protect against future snafus .. I know it's redundant as the code stands.
> Viz:
> 
>          HReg (*iselExpr)(ISelEnv*, IRExpr*) = NULL;
>          ARM64Instr* (*VCmp)(HReg, HReg) = NULL
Good point! initialised.
Bugs caused by uninitialised data can be insidious. The code is fine now but possible future changes in the subsequent if clauses could allow such bugs to appear.
Comment 6 ahashmi 2021-06-29 16:21:31 UTC
Landed c5331315d7a62ec1c117ff773fadfeb0bf433b02