From 07c197e8d0dc542fdef1142d8a172cfe48d1d3e8 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Fri, 12 Oct 2018 05:21:51 -0400
Subject: [PATCH] constant_propagation_pass: Add 64-bit variants of shifts to
 the pass

These optimizations can also apply to the 64-bit variants of the shift
opcodes; we just need to check if the instruction has an associated
pseudo-op before performing the 32-bit variant's specifics.

While we're at it, we can also relocate the code to its own function
like the rest of the cases to keep organization consistent.
---
 src/ir_opt/constant_propagation_pass.cpp | 40 +++++++++++++++---------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/ir_opt/constant_propagation_pass.cpp b/src/ir_opt/constant_propagation_pass.cpp
index f02ba264..887755e4 100644
--- a/src/ir_opt/constant_propagation_pass.cpp
+++ b/src/ir_opt/constant_propagation_pass.cpp
@@ -154,6 +154,26 @@ void FoldOR(IR::Inst& inst, bool is_32_bit) {
     }
 }
 
+void FoldShifts(IR::Inst& inst) {
+    IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
+
+    // The 32-bit variants can contain 3 arguments, while the
+    // 64-bit variants only contain 2.
+    if (inst.NumArgs() == 3 && !carry_inst) {
+        inst.SetArg(2, IR::Value(false));
+    }
+
+    const auto shift_amount = inst.GetArg(1);
+    if (!shift_amount.IsZero()) {
+        return;
+    }
+
+    if (carry_inst) {
+        carry_inst->ReplaceUsesWith(inst.GetArg(2));
+    }
+    inst.ReplaceUsesWith(inst.GetArg(0));
+}
+
 void FoldSignExtendXToWord(IR::Inst& inst) {
     if (!inst.AreAllArgsImmediates()) {
         return;
@@ -197,23 +217,15 @@ void ConstantPropagation(IR::Block& block) {
 
         switch (opcode) {
         case IR::Opcode::LogicalShiftLeft32:
+        case IR::Opcode::LogicalShiftLeft64:
         case IR::Opcode::LogicalShiftRight32:
+        case IR::Opcode::LogicalShiftRight64:
         case IR::Opcode::ArithmeticShiftRight32:
-        case IR::Opcode::RotateRight32: {
-            if (!inst.GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp)) {
-                inst.SetArg(2, IR::Value(false));
-            }
-
-            auto shift_amount = inst.GetArg(1);
-            if (shift_amount.IsImmediate() && shift_amount.GetU8() == 0) {
-                IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
-                if (carry_inst) {
-                    carry_inst->ReplaceUsesWith(inst.GetArg(2));
-                }
-                inst.ReplaceUsesWith(inst.GetArg(0));
-            }
+        case IR::Opcode::ArithmeticShiftRight64:
+        case IR::Opcode::RotateRight32:
+        case IR::Opcode::RotateRight64:
+            FoldShifts(inst);
             break;
-        }
         case IR::Opcode::Mul32:
         case IR::Opcode::Mul64:
             FoldMultiply(inst, opcode == IR::Opcode::Mul32);