[PATCH] D126089: [WPD] Make sure type test is eliminated

Arthur Eubanks via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 13:19:58 PDT 2022


aeubanks created this revision.
Herald added subscribers: ormris, hiraditya.
Herald added a project: All.
aeubanks requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

The i1 from a type.test may be merged with another type.test into a phi
which gets fed to an assume. Previously we wouldn't delete the type.test
in some cases, causing an assume(false). Now RAUW with true to make sure
we can delete the type.test.

LTT already handles this case, do something similar here.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126089

Files:
  llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
  llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-assume-phi.ll


Index: llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-assume-phi.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-assume-phi.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility %s 2>&1 | FileCheck %s
+
+define void @call(ptr %obj, i1 %i) {
+; CHECK-LABEL: @call(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[I:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[VTABLE:%.*]] = load ptr, ptr [[OBJ:%.*]], align 8
+; CHECK-NEXT:    [[FPTR:%.*]] = load ptr, ptr [[VTABLE]], align 8
+; CHECK-NEXT:    call void [[FPTR]](ptr [[OBJ]])
+; CHECK-NEXT:    br label [[FIN:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[VTABLE2:%.*]] = load ptr, ptr [[OBJ]], align 8
+; CHECK-NEXT:    [[FPTR2:%.*]] = load ptr, ptr [[VTABLE2]], align 8
+; CHECK-NEXT:    call void [[FPTR2]](ptr [[OBJ]])
+; CHECK-NEXT:    br label [[FIN]]
+; CHECK:       fin:
+; CHECK-NEXT:    [[PN:%.*]] = phi i1 [ true, [[BB1]] ], [ true, [[BB2]] ]
+; CHECK-NEXT:    call void @llvm.assume(i1 [[PN]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %i, label %bb1, label %bb2
+bb1:
+  %vtable = load ptr, ptr %obj
+  %fptr = load ptr, ptr %vtable
+  call void %fptr(ptr %obj)
+  %p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid")
+  br label %fin
+bb2:
+  %vtable2 = load ptr, ptr %obj
+  %fptr2 = load ptr, ptr %vtable2
+  call void %fptr2(ptr %obj)
+  %p2 = call i1 @llvm.type.test(ptr %vtable2, metadata !"typeid")
+  br label %fin
+fin:
+  %pn = phi i1 [ %p, %bb1 ], [ %p2, %bb2 ]
+  call void @llvm.assume(i1 %pn)
+  ret void
+}
+
+declare i1 @llvm.type.test(ptr, metadata)
+declare void @llvm.assume(i1)
+
+!0 = !{i32 0, !"typeid"}
Index: llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
===================================================================
--- llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -1923,10 +1923,13 @@
       // We no longer need the assumes or the type test.
       for (auto Assume : Assumes)
         Assume->eraseFromParent();
+      // We may run into multiple type tests feeding into a phi. In that case
+      // RAUW true and leave the assume.
+      if (!CI->use_empty())
+        CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
       // We can't use RecursivelyDeleteTriviallyDeadInstructions here because we
       // may use the vtable argument later.
-      if (CI->use_empty())
-        CI->eraseFromParent();
+      CI->eraseFromParent();
     };
 
     // At this point we could remove all type test assume sequences, as they


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D126089.431037.patch
Type: text/x-patch
Size: 2768 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220520/274f2219/attachment.bin>


More information about the llvm-commits mailing list