e9c5e8
commit 6aa4f7e7e76b40c183fb29650540d119ce1b4a4a
e9c5e8
Author: Julian Seward <jseward@acm.org>
e9c5e8
Date:   Thu Jun 11 09:01:52 2020 +0200
e9c5e8
e9c5e8
    expr_is_guardable, stmt_is_guardable, add_guarded_stmt_to_end_of: handle GetI/PutI cases.
e9c5e8
    
e9c5e8
    This fixes #422715.
e9c5e8
e9c5e8
diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c
e9c5e8
index 2f204c5b0..0cee970e4 100644
e9c5e8
--- a/VEX/priv/guest_generic_bb_to_IR.c
e9c5e8
+++ b/VEX/priv/guest_generic_bb_to_IR.c
e9c5e8
@@ -425,6 +425,7 @@ static Bool expr_is_guardable ( const IRExpr* e )
e9c5e8
       case Iex_ITE:
e9c5e8
       case Iex_CCall:
e9c5e8
       case Iex_Get:
e9c5e8
+      case Iex_GetI:
e9c5e8
       case Iex_Const:
e9c5e8
       case Iex_RdTmp:
e9c5e8
          return True;
e9c5e8
@@ -450,6 +451,7 @@ static Bool stmt_is_guardable ( const IRStmt* st )
e9c5e8
       case Ist_NoOp:
e9c5e8
       case Ist_IMark:
e9c5e8
       case Ist_Put:
e9c5e8
+      case Ist_PutI:
e9c5e8
          return True;
e9c5e8
       // These are definitely not guardable, or at least it's way too much
e9c5e8
       // hassle to do so.
e9c5e8
@@ -506,7 +508,7 @@ static void add_guarded_stmt_to_end_of ( /*MOD*/IRSB* bb,
e9c5e8
          // Put(offs, e) ==> Put(offs, ITE(guard, e, Get(offs, sizeof(e))))
e9c5e8
          // Which when flattened out is:
e9c5e8
          //   t1 = Get(offs, sizeof(e))
e9c5e8
-         //   t2 = ITE(guard, e, t2)
e9c5e8
+         //   t2 = ITE(guard, e, t1)
e9c5e8
          //   Put(offs, t2)
e9c5e8
          Int offset = st->Ist.Put.offset;
e9c5e8
          IRExpr* e = st->Ist.Put.data;
e9c5e8
@@ -519,6 +521,26 @@ static void add_guarded_stmt_to_end_of ( /*MOD*/IRSB* bb,
e9c5e8
          addStmtToIRSB(bb, IRStmt_Put(offset, IRExpr_RdTmp(t2)));
e9c5e8
          break;
e9c5e8
       }
e9c5e8
+      case Ist_PutI: {
e9c5e8
+         // PutI(descr,ix,bias, e) ==> Put(descr,ix,bias, ITE(guard, e, GetI(descr,ix,bias)))
e9c5e8
+         // Which when flattened out is:
e9c5e8
+         //   t1 = GetI(descr,ix,bias)
e9c5e8
+         //   t2 = ITE(guard, e, t1)
e9c5e8
+         //   PutI(descr,ix,bias, t2)
e9c5e8
+         IRPutI*     details = st->Ist.PutI.details;
e9c5e8
+         IRRegArray* descr   = details->descr;
e9c5e8
+         IRExpr*     ix      = details->ix;
e9c5e8
+         Int         bias    = details->bias;
e9c5e8
+         IRExpr*     e       = details->data;
e9c5e8
+         IRType ty = typeOfIRExpr(bb->tyenv, e);
e9c5e8
+         IRTemp t1 = newIRTemp(bb->tyenv, ty);
e9c5e8
+         IRTemp t2 = newIRTemp(bb->tyenv, ty);
e9c5e8
+         addStmtToIRSB(bb, IRStmt_WrTmp(t1, IRExpr_GetI(descr,ix,bias)));
e9c5e8
+         addStmtToIRSB(bb, IRStmt_WrTmp(t2, IRExpr_ITE(IRExpr_RdTmp(guard),
e9c5e8
+                                                       e, IRExpr_RdTmp(t1))));
e9c5e8
+         addStmtToIRSB(bb, IRStmt_PutI(mkIRPutI(descr,ix,bias, IRExpr_RdTmp(t2))));
e9c5e8
+         break;
e9c5e8
+      }
e9c5e8
       case Ist_Exit: {
e9c5e8
          // Exit(xguard, dst, jk, offsIP)
e9c5e8
          // ==> t1 = And1(xguard, guard)