[GVN] Improve PRE on load instructions
authorGuozhi Wei <carrot@google.com>
Mon, 9 Jan 2023 23:04:41 +0000 (23:04 +0000)
committerGuozhi Wei <carrot@google.com>
Mon, 9 Jan 2023 23:08:41 +0000 (23:08 +0000)
commit1f1d501843e5cf8741599035d6ef66a3eb5e1e9e
tree50e32535806b85faa7f8d9e290fcc9ea17e0d735
parent056d4dca7764d92870f717906e7edb4a9563d3cb
[GVN] Improve PRE on load instructions

This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

 LoadBB:
   v1 = load %addr
   ...

 PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

 SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D139582
llvm/include/llvm/Transforms/Scalar/GVN.h
llvm/lib/Transforms/Scalar/GVN.cpp
llvm/test/Transforms/GVN/PRE/2011-06-01-NonLocalMemdepMiscompile.ll
llvm/test/Transforms/GVN/PRE/2017-06-28-pre-load-dbgloc.ll
llvm/test/Transforms/GVN/PRE/pre-load.ll
llvm/test/Transforms/GVN/PRE/volatile.ll
llvm/test/Transforms/GVN/condprop.ll