[PATCH] D105392: [InstCombine] Add optimization to prevent poison from being propagated.

Hyeongyu Kim via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 3 02:34:17 PDT 2021


hyeongyukim created this revision.
Herald added a subscriber: hiraditya.
hyeongyukim requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

In D104569 <https://reviews.llvm.org/D104569>, Freeze was inserted just before br to solve the `branching on undef` miscompilation problem.
But value analysis was being disturbed by added freeze.

  v = load ptr
  cond = freeze(icmp (and v, const), const')
  br cond, ...
  ``
  The case in which value analysis disturbed is as above.
  By changing freeze to add immediately after load, value analysis will be successful again.

v = load ptr
freeze(icmp (and v, const), const')

>
=

v = load ptr
v' = freeze v
icmp (and v', const), const'

  In this patch, I propose the above optimization.
  With this patch, the poison will not spread as the freeze is performed early.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105392

Files:
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/test/Transforms/InstCombine/freeze.ll


Index: llvm/test/Transforms/InstCombine/freeze.ll
===================================================================
--- llvm/test/Transforms/InstCombine/freeze.ll
+++ llvm/test/Transforms/InstCombine/freeze.ll
@@ -86,3 +86,20 @@
   call void @use_i32_i1(i32 %a, i1 %b)
   ret void
 }
+
+; Add freeze immediately after load. It prevents the poison from being propagated.
+
+define i1 @freeze_icmp_and_load(i32* %ptr) {
+; CHECK-LABEL: @freeze_icmp_and_load(
+; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[PTR:%.*]], align 4
+; CHECK-NEXT:    [[V_FR:%.*]] = freeze i32 [[V]]
+; CHECK-NEXT:    [[W:%.*]] = and i32 [[V_FR]], 1
+; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[W]], 0
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %v = load i32, i32* %ptr
+  %w = and i32 %v, 1
+  %cond = icmp eq i32 %w, 0
+  %cond.fr = freeze i1 %cond
+  ret i1 %cond.fr
+}
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3525,6 +3525,25 @@
       return NV;
   }
 
+  //   v = load ptr
+  //   freeze(icmp (and v, const), const')
+  // =>
+  //   v = load ptr
+  //   v' = freeze v
+  //   icmp (and v', const), const'
+  ICmpInst::Predicate Pred;
+  Value *W;
+  if (match(Op0, m_ICmp(Pred, m_And(m_Value(W), m_ConstantInt()),
+                        m_ConstantInt()))) {
+    if (auto *LI = dyn_cast<LoadInst>(W)) {
+      auto *FI = new FreezeInst(LI, LI->getName() + ".fr");
+      FI->insertAfter(LI);
+      LI->replaceUsesWithIf(
+          FI, [&](Use &U) { return !isa<FreezeInst>(U.getUser()); });
+      return replaceInstUsesWith(I, Op0);
+    }
+  }
+
   if (match(Op0, m_Undef())) {
     // If I is freeze(undef), see its uses and fold it to the best constant.
     // - or: pick -1


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105392.356334.patch
Type: text/x-patch
Size: 1882 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210703/c9b45375/attachment.bin>


More information about the llvm-commits mailing list