[llvm] eda61fb - [SelectOpti] Fix lifetime intrinsic bug

Sotiris Apostolakis via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 13 12:15:10 PDT 2022


Author: Sotiris Apostolakis
Date: 2022-09-13T19:00:18Z
New Revision: eda61fb656ab9e7b38330a94031ae1aac90eae3a

URL: https://github.com/llvm/llvm-project/commit/eda61fb656ab9e7b38330a94031ae1aac90eae3a
DIFF: https://github.com/llvm/llvm-project/commit/eda61fb656ab9e7b38330a94031ae1aac90eae3a.diff

LOG: [SelectOpti] Fix lifetime intrinsic bug

When a select is converted to a branch and load instructions are sinked to the true/false blocks,
lifetime intrinsics (if present) could be made unsound if not moved.

This conservatively moves all lifetime intrinsics in a transformed BB to the end block to ensure
preserved lifetime semantics.

Reviewed By: davidxl

Differential Revision: https://reviews.llvm.org/D133777

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectOptimize.cpp
    llvm/test/CodeGen/X86/select-optimize.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp
index 75c2eebbdacd8..ff1df22a48f7f 100644
--- a/llvm/lib/CodeGen/SelectOptimize.cpp
+++ b/llvm/lib/CodeGen/SelectOptimize.cpp
@@ -29,6 +29,7 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/ProfDataUtils.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
@@ -469,6 +470,22 @@ void SelectOptimize::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
       auto *FalseBranch = BranchInst::Create(EndBlock, FalseBlock);
       FalseBranch->setDebugLoc(SI->getDebugLoc());
     }
+    // If there was sinking, move any lifetime-end intrinsic calls found in the
+    // StartBlock to the newly-created end block to ensure sound lifetime info
+    // after sinking (in case any use is sinked).
+    else {
+      SmallVector<Instruction *, 2> EndLifetimeCalls;
+      for (Instruction &I : *StartBlock) {
+        if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I)) {
+          if (II->getIntrinsicID() == Intrinsic::lifetime_end) {
+            EndLifetimeCalls.push_back(&I);
+          }
+        }
+      }
+      for (auto *LC : EndLifetimeCalls) {
+        LC->moveBefore(&*EndBlock->getFirstInsertionPt());
+      }
+    }
 
     // Insert the real conditional branch based on the original condition.
     // If we did not create a new block for one of the 'true' or 'false' paths

diff  --git a/llvm/test/CodeGen/X86/select-optimize.ll b/llvm/test/CodeGen/X86/select-optimize.ll
index 2f2fca4a7f994..ebc53bea6e13a 100644
--- a/llvm/test/CodeGen/X86/select-optimize.ll
+++ b/llvm/test/CodeGen/X86/select-optimize.ll
@@ -187,6 +187,7 @@ define i32 @expensive_val_operand2(ptr nocapture %a, i32 %x, i1 %cmp) {
 
 ; Cold value operand with load in its one-use dependence slice shoud result
 ; into a branch with sinked dependence slice.
+; The lifetime-end intrinsics should be soundly preserved.
 define i32 @expensive_val_operand3(ptr nocapture %a, i32 %b, i32 %y, i1 %cmp) {
 ; CHECK-LABEL: @expensive_val_operand3(
 ; CHECK-NEXT:    [[SEL_FROZEN:%.*]] = freeze i1 [[CMP:%.*]]
@@ -197,9 +198,11 @@ define i32 @expensive_val_operand3(ptr nocapture %a, i32 %b, i32 %y, i1 %cmp) {
 ; CHECK-NEXT:    br label [[SELECT_END]]
 ; CHECK:       select.end:
 ; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[X]], [[SELECT_TRUE_SINK]] ], [ [[Y:%.*]], [[TMP0:%.*]] ]
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr nonnull [[A]])
 ; CHECK-NEXT:    ret i32 [[SEL]]
 ;
   %load = load i32, ptr %a, align 8
+  call void @llvm.lifetime.end.p0(i64 2, ptr nonnull %a)
   %x = add i32 %load, %b
   %sel = select i1 %cmp, i32 %x, i32 %y, !prof !17
   ret i32 %sel
@@ -447,6 +450,9 @@ for.body:                                         ; preds = %for.body.preheader,
 ; Function Attrs: nounwind readnone speculatable willreturn
 declare void @llvm.dbg.value(metadata, metadata, metadata)
 
+; Function Attrs: argmemonly mustprogress nocallback nofree nosync nounwind willreturn
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
+
 !llvm.module.flags = !{!0, !26, !27}
 !0 = !{i32 1, !"ProfileSummary", !1}
 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}


        


More information about the llvm-commits mailing list