[llvm] bccc9aa - Don't vectorize PHIs in catchswitch blocks

William Schmidt via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 19 06:10:55 PDT 2022


Author: William Schmidt
Date: 2022-07-19T06:10:17-07:00
New Revision: bccc9aa81c1c1d212acd3314895731ec4de30e35

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

LOG: Don't vectorize PHIs in catchswitch blocks

We currently assert in vectorizeTree(TreeEntry*) when processing a PHI
bundle in a block containing a catchswitch.  We attempt to set the
IRBuilder insertion point following the catchswitch, which is invalid.
This is done so that ShuffleBuilder.finalize() knows where to insert
a shuffle if one is needed.

To avoid this occurring, watch out for catchswitch blocks during
buildTree_rec() processing, and avoid adding PHIs in such blocks to
the vectorizable tree.  It is unlikely that constraining vectorization
over an exception path will cause a noticeable performance loss, so
this seems preferable to trying to anticipate when a shuffle will and
will not be required.

Added: 
    llvm/test/Transforms/SLPVectorizer/X86/catchswitch.ll

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b75c4d32cee2..cd044c78d900 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -4814,6 +4814,15 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
     return;
   }
 
+  // Don't go into catchswitch blocks, which can happen with PHIs.
+  // Such blocks can only have PHIs and the catchswitch.  There is no
+  // place to insert a shuffle if we need to, so just avoid that issue.
+  if (isa<CatchSwitchInst>(BB->getTerminator())) {
+    LLVM_DEBUG(dbgs() << "SLP: bundle in catchswitch block.\n");
+    newTreeEntry(VL, None /*not vectorized*/, S, UserTreeIdx);
+    return;
+  }
+
   // Check that every instruction appears once in this bundle.
   if (!TryToFindDuplicates(S))
     return;

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/catchswitch.ll b/llvm/test/Transforms/SLPVectorizer/X86/catchswitch.ll
new file mode 100644
index 000000000000..29d3638c91e3
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/catchswitch.ll
@@ -0,0 +1,93 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -slp-vectorizer -S -mtriple=x86_64-pc-windows-msvc19.29.30145 < %s | FileCheck %s
+
+; This used to crash in SLP vectorization when attempting to set the
+; IRBuilder's insertion point to the end of a catchswitch block, which
+; is invalid.  Only phis and the catchswitch may be present, so we must
+; avoid trying to insert shuffles into such a block.
+
+%typeA = type { i8**, i8*, [20 x i8] }
+ at globalA = external global %typeA
+
+declare i32 @__CxxFrameHandler3(...)
+declare void @funcA()
+
+define void @important_func() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+; CHECK-LABEL: @important_func(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LABELB:%.*]]
+; CHECK:       labelB:
+; CHECK-NEXT:    invoke void @funcA()
+; CHECK-NEXT:    to label [[LABELC:%.*]] unwind label [[LABELD:%.*]]
+; CHECK:       labelC:
+; CHECK-NEXT:    invoke void @funcA()
+; CHECK-NEXT:    to label [[LABELE:%.*]] unwind label [[LABELF:%.*]]
+; CHECK:       labelD:
+; CHECK-NEXT:    [[TMP0:%.*]] = cleanuppad within none []
+; CHECK-NEXT:    unreachable
+; CHECK:       labelE:
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 1
+; CHECK-NEXT:    [[F:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 2
+; CHECK-NEXT:    invoke void @funcA()
+; CHECK-NEXT:    to label [[LABELG:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
+; CHECK:       labelF:
+; CHECK-NEXT:    [[TMP2:%.*]] = cleanuppad within none []
+; CHECK-NEXT:    cleanupret from [[TMP2]] unwind to caller
+; CHECK:       labelG:
+; CHECK-NEXT:    [[G:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 0
+; CHECK-NEXT:    [[H:%.*]] = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 3
+; CHECK-NEXT:    invoke void @funcA()
+; CHECK-NEXT:    to label [[LABELH:%.*]] unwind label [[CATCH_DISPATCH]]
+; CHECK:       labelH:
+; CHECK-NEXT:    unreachable
+; CHECK:       catch.dispatch:
+; CHECK-NEXT:    [[TMP3:%.*]] = phi float [ [[G]], [[LABELG]] ], [ [[TMP1]], [[LABELE]] ]
+; CHECK-NEXT:    [[TMP4:%.*]] = phi float [ [[H]], [[LABELG]] ], [ [[F]], [[LABELE]] ]
+; CHECK-NEXT:    [[TMP5:%.*]] = catchswitch within none [label %catch] unwind to caller
+; CHECK:       catch:
+; CHECK-NEXT:    [[TMP6:%.*]] = catchpad within [[TMP5]] [%typeA* @globalA, i32 8, i8* null]
+; CHECK-NEXT:    unreachable
+;
+entry:
+  br label %labelB
+
+labelB:
+  invoke void @funcA()
+  to label %labelC unwind label %labelD
+
+labelC:
+  invoke void @funcA()
+  to label %labelE unwind label %labelF
+
+labelD:
+  %0 = cleanuppad within none []
+  unreachable
+
+labelE:
+  %1 = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 1
+  %f = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 2
+  invoke void @funcA()
+  to label %labelG unwind label %catch.dispatch
+
+labelF:
+  %2 = cleanuppad within none []
+  cleanupret from %2 unwind to caller
+
+labelG:
+  %g = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 0
+  %h = extractelement <4 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000>, i64 3
+  invoke void @funcA()
+  to label %labelH unwind label %catch.dispatch
+
+labelH:
+  unreachable
+
+catch.dispatch:
+  %3 = phi float [ %g, %labelG ], [ %1, %labelE ]
+  %4 = phi float [ %h, %labelG ], [ %f, %labelE ]
+  %5 = catchswitch within none [label %catch] unwind to caller
+
+catch:
+  %6 = catchpad within %5 [%typeA* @globalA, i32 8, i8* null]
+  unreachable
+}


        


More information about the llvm-commits mailing list