diff --git a/dartagnan/src/main/antlr4/LitmusAArch64.g4 b/dartagnan/src/main/antlr4/LitmusAArch64.g4
index 152c34d8e4..bae408b323 100644
--- a/dartagnan/src/main/antlr4/LitmusAArch64.g4
+++ b/dartagnan/src/main/antlr4/LitmusAArch64.g4
@@ -76,6 +76,8 @@ instruction
     |   branchRegister
     |   branchLabel
     |   fence
+    |   return
+    |   nop
     ;
 
 mov locals [String rD, int size]
@@ -131,6 +133,14 @@ branchLabel
     :   label Colon
     ;
 
+return
+    :   Ret
+    ;
+
+nop
+    :   Nop
+    ;
+
 loadInstruction locals [String mo]
     :   LDR     {$mo = MO_RX;}
     |   LDAR    {$mo = MO_ACQ;}
@@ -252,7 +262,7 @@ location
     ;
 
 immediate
-    :   Num constant
+    :   Num Hexa? constant
     ;
 
 label
@@ -265,6 +275,18 @@ assertionValue
     |   constant
     ;
 
+Hexa
+    :   '0x'
+    ;
+
+Ret
+    :   'ret'
+    ;
+
+Nop
+    :   'nop'
+    ;
+
 Locations
     :   'locations'
     ;
@@ -371,10 +393,12 @@ BitfieldOperator
 
 Register64
     :   'X' DigitSequence
+    |   'XZR' // zero register
     ;
 
 Register32
     :   'W' DigitSequence
+    |   'WZR' // zero register
     ;
 
 LitmusLanguage
diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/utils/ProgramBuilder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/utils/ProgramBuilder.java
index b0bff0d508..1d1e773a9a 100644
--- a/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/utils/ProgramBuilder.java
+++ b/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/utils/ProgramBuilder.java
@@ -7,12 +7,14 @@
 import com.dat3m.dartagnan.expression.Type;
 import com.dat3m.dartagnan.expression.integers.IntLiteral;
 import com.dat3m.dartagnan.expression.type.FunctionType;
+import com.dat3m.dartagnan.expression.type.IntegerType;
 import com.dat3m.dartagnan.expression.type.TypeFactory;
 import com.dat3m.dartagnan.program.*;
 import com.dat3m.dartagnan.program.Thread;
 import com.dat3m.dartagnan.program.Program.SourceLanguage;
 import com.dat3m.dartagnan.program.event.Event;
 import com.dat3m.dartagnan.program.event.EventFactory;
+import com.dat3m.dartagnan.program.event.RegWriter;
 import com.dat3m.dartagnan.program.event.core.Label;
 import com.dat3m.dartagnan.program.event.core.threading.ThreadStart;
 import com.dat3m.dartagnan.program.event.metadata.OriginalId;
@@ -89,6 +91,27 @@ public static void processAfterParsing(Program program) {
         }
     }
 
+    public static void replaceZeroRegisters(Program program, List<String> zeroRegNames) {
+        for (Function func : Iterables.concat(program.getThreads(), program.getFunctions())) {
+            if (func.hasBody()) {
+                for (String zeroRegName : zeroRegNames) {
+                    Register zr = func.getRegister(zeroRegName);
+                    if (zr != null) {
+                        for (RegWriter rw : func.getEvents(RegWriter.class)) {
+                            if (rw.getResultRegister().equals(zr)) {
+                                Register dummy = rw.getThread().getOrNewRegister("__zeroRegDummy_" + zr.getName(), zr.getType());
+                                rw.setResultRegister(dummy);
+                            }
+                        }
+                        // This comes after the loop to avoid the renaming in the initialization event
+                        Event initToZero = EventFactory.newLocal(zr, expressions.makeGeneralZero(zr.getType()));
+                        func.getEntry().insertAfter(initToZero);
+                    }
+                }
+            }
+        }
+    }
+
     // ----------------------------------------------------------------------------------------------------------------
     // Misc
 
diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusAArch64.java b/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusAArch64.java
index 4c0d1e5091..455c285ad0 100644
--- a/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusAArch64.java
+++ b/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusAArch64.java
@@ -17,9 +17,13 @@
 import com.dat3m.dartagnan.program.event.core.Label;
 import com.dat3m.dartagnan.program.event.core.Load;
 
+import java.math.BigInteger;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
+import static com.dat3m.dartagnan.parsers.program.utils.ProgramBuilder.replaceZeroRegisters;
+
 public class VisitorLitmusAArch64 extends LitmusAArch64BaseVisitor<Object> {
 
     private static class CmpInstruction {
@@ -53,10 +57,11 @@ public Object visitMain(LitmusAArch64Parser.MainContext ctx) {
         visitVariableDeclaratorList(ctx.variableDeclaratorList());
         visitInstructionList(ctx.program().instructionList());
         VisitorLitmusAssertions.parseAssertions(programBuilder, ctx.assertionList(), ctx.assertionFilter());
-        return programBuilder.build();
+        Program prog = programBuilder.build();
+        replaceZeroRegisters(prog, Arrays.asList("XZR, WZR"));
+        return prog;
     }
 
-
     // ----------------------------------------------------------------------------------------------------------------
     // Variable declarator list, e.g., { 0:EAX=0; 1:EAX=1; x=2; }
 
@@ -211,6 +216,12 @@ public Object visitFence(LitmusAArch64Parser.FenceContext ctx) {
         return programBuilder.addChild(mainThread, EventFactory.newFenceOpt(ctx.Fence().getText(), ctx.opt));
     }
 
+    @Override
+    public Object visitReturn(LitmusAArch64Parser.ReturnContext ctx) {
+        Label end = programBuilder.getEndOfThreadLabel(mainThread);
+        return programBuilder.addChild(mainThread, EventFactory.newGoto(end));
+    }
+
     @Override
     public Expression visitExpressionRegister64(LitmusAArch64Parser.ExpressionRegister64Context ctx) {
         Expression expr = programBuilder.getOrNewRegister(mainThread, ctx.register64().id, archType);
@@ -255,4 +266,12 @@ private Register visitOffset(LitmusAArch64Parser.OffsetContext ctx, Register reg
         programBuilder.addChild(mainThread, EventFactory.newLocal(result, expressions.makeAdd(register, expr)));
         return result;
     }
+
+    @Override
+    public Expression visitImmediate(LitmusAArch64Parser.ImmediateContext ctx) {
+        final int radix = ctx.Hexa() != null ? 16 : 10;
+        BigInteger value = new BigInteger(ctx.constant().getText(), radix);
+        return expressions.makeValue(value, archType);
+    }
+
 }
diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusRISCV.java b/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusRISCV.java
index 8959730977..92568decfd 100644
--- a/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusRISCV.java
+++ b/dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLitmusRISCV.java
@@ -1,12 +1,11 @@
 package com.dat3m.dartagnan.parsers.program.visitors;
 
+import java.util.Arrays;
 import com.dat3m.dartagnan.configuration.Arch;
 import com.dat3m.dartagnan.exception.ParsingException;
 import com.dat3m.dartagnan.expression.Expression;
 import com.dat3m.dartagnan.expression.ExpressionFactory;
-import com.dat3m.dartagnan.expression.ExpressionVisitor;
 import com.dat3m.dartagnan.expression.integers.IntLiteral;
-import com.dat3m.dartagnan.expression.processing.ExprTransformer;
 import com.dat3m.dartagnan.expression.type.IntegerType;
 import com.dat3m.dartagnan.expression.type.TypeFactory;
 import com.dat3m.dartagnan.parsers.LitmusRISCVBaseVisitor;
@@ -16,10 +15,11 @@
 import com.dat3m.dartagnan.program.Register;
 import com.dat3m.dartagnan.program.event.Event;
 import com.dat3m.dartagnan.program.event.EventFactory;
-import com.dat3m.dartagnan.program.event.RegReader;
 import com.dat3m.dartagnan.program.event.Tag;
 import com.dat3m.dartagnan.program.event.core.Label;
 
+import static com.dat3m.dartagnan.parsers.program.utils.ProgramBuilder.replaceZeroRegisters;
+
 public class VisitorLitmusRISCV extends LitmusRISCVBaseVisitor<Object> {
 
     private final ProgramBuilder programBuilder = ProgramBuilder.forArch(Program.SourceLanguage.LITMUS, Arch.RISCV);
@@ -42,32 +42,10 @@ public Object visitMain(LitmusRISCVParser.MainContext ctx) {
         visitInstructionList(ctx.program().instructionList());
         VisitorLitmusAssertions.parseAssertions(programBuilder, ctx.assertionList(), ctx.assertionFilter());
         Program prog = programBuilder.build();
-        replaceX0Register(prog);
-
+        replaceZeroRegisters(prog, Arrays.asList("x0"));
         return prog;
     }
 
-    /*
-    The "x0" register plays a special role in RISCV:
-      1. Reading accesses always return the value 0.
-      2. Writing accesses are discarded.
-     TODO: The below code is a simple fix to guarantee point 1. above.
-      Point 2. might also be resolved: although we do not prevent writing to x0,
-      the value of x0 is never read after the transformation so its value is effectively 0.
-      However, the exists/forall clauses could still refer to that register and observe a non-zero value.
-     */
-    private void replaceX0Register(Program program) {
-        final ExpressionVisitor<Expression> x0Replacer = new ExprTransformer() {
-            @Override
-            public Expression visitRegister(Register reg) {
-                return reg.getName().equals("x0") ? expressions.makeGeneralZero(reg.getType()) : reg;
-            }
-        };
-        program.getThreadEvents(RegReader.class)
-                .forEach(e -> e.transformExpressions(x0Replacer));
-    }
-
-
     // ----------------------------------------------------------------------------------------------------------------
     // Variable declarator list
 
diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java
index 60b209d087..451fc3678c 100644
--- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java
+++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ProcessingManager.java
@@ -96,7 +96,7 @@ private ProcessingManager(Configuration config) throws InvalidConfigurationExcep
                                 ComplexBlockSplitting.newInstance(),
                                 BranchReordering.fromConfig(config),
                                 Simplifier.fromConfig(config)
-                        ), Target.FUNCTIONS, true
+                        ), Target.ALL, true
                 ),
                 ProgramProcessor.fromFunctionProcessor(NormalizeLoops.newInstance(), Target.ALL, true),
                 RegisterDecomposition.newInstance(),
diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java
index c02bd2aa9a..32db0c5cff 100644
--- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java
+++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java
@@ -238,16 +238,8 @@ private EventGraph computeInternalDependencies(Set<Register.UsageType> usageType
                 reader.getRegisterReads().forEach(read -> {
                     if (usageTypes.contains(read.usageType())) {
                         Register register = read.register();
-                        // TODO: Update after this is merged
-                        //  https://github.com/hernanponcedeleon/Dat3M/pull/741
-                        // Register x0 is hardwired to the constant 0 in RISCV
-                        // https://en.wikichip.org/wiki/risc-v/registers,
-                        // and thus it generates no dependency, see
-                        // https://github.com/herd/herdtools7/issues/408
-                        if (!program.getArch().equals(RISCV) || !register.getName().equals("x0")) {
-                            state.ofRegister(register).getMayWriters().forEach(writer ->
-                                    data.computeIfAbsent(writer, x -> new HashSet<>()).add(reader));
-                        }
+                        state.ofRegister(register).getMayWriters()
+                                .forEach(writer -> data.computeIfAbsent(writer, x -> new HashSet<>()).add(reader));
                     }
                 });
             });
diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java
index dca921255b..e2cf68ff7b 100644
--- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java
+++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java
@@ -40,7 +40,6 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static com.dat3m.dartagnan.configuration.Arch.RISCV;
 import static com.dat3m.dartagnan.program.Register.UsageType.*;
 import static com.dat3m.dartagnan.program.event.Tag.*;
 import static com.google.common.base.Preconditions.checkArgument;
@@ -915,16 +914,6 @@ private MutableKnowledge computeInternalDependencies(Set<UsageType> usageTypes)
                         continue;
                     }
                     final Register register = regRead.register();
-                    // TODO: Update after this is merged
-                    //  https://github.com/hernanponcedeleon/Dat3M/pull/741
-                    // Register x0 is hardwired to the constant 0 in RISCV
-                    // https://en.wikichip.org/wiki/risc-v/registers,
-                    // and thus it generates no dependency, see
-                    // https://github.com/herd/herdtools7/issues/408
-                    // TODO: Can't we just replace all reads of "x0" by 0 in RISC-specific preprocessing?
-                    if (program.getArch().equals(RISCV) && register.getName().equals("x0")) {
-                        continue;
-                    }
                     final List<? extends Event> writers = state.ofRegister(register).getMayWriters();
                     for (Event regWriter : writers) {
                         may.add(regWriter, regReader);