[PATCH] D79261: [MergeFuncs] Don't merge shufflevectors with different masks

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 17:17:14 PDT 2020


nikic created this revision.
nikic added reviewers: efriedma, vsk.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
efriedma accepted this revision.
efriedma added a comment.
This revision is now accepted and ready to land.

LGTM

I thought I caught all the places that needed new code to compare masks, but I missed this; thanks.


When the shufflevector mask operand was converted into special instruction data, the FunctionComparator was not updated to account for this. As such, MergeFuncs will happily merge shufflevectors with different masks.

This fixes https://bugs.llvm.org/show_bug.cgi?id=45773.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79261

Files:
  lib/Transforms/Utils/FunctionComparator.cpp
  test/Transforms/MergeFunc/shufflevector.ll


Index: test/Transforms/MergeFunc/shufflevector.ll
===================================================================
--- /dev/null
+++ test/Transforms/MergeFunc/shufflevector.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+
+define internal <2 x i32> @test1(<2 x i32> %v1, <2 x i32> %v2) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:    [[X:%.*]] = shufflevector <2 x i32> [[V1:%.*]], <2 x i32> [[V2:%.*]], <2 x i32> <i32 0, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[X]]
+;
+  %x = shufflevector <2 x i32> %v1, <2 x i32> %v2, <2 x i32> <i32 0, i32 1>
+  ret <2 x i32> %x
+}
+
+; Same mask as test1.
+define internal <2 x i32> @test2(<2 x i32> %v1, <2 x i32> %v2) {
+  %x = shufflevector <2 x i32> %v1, <2 x i32> %v2, <2 x i32> <i32 0, i32 1>
+  ret <2 x i32> %x
+}
+
+; Different mask than test1, don't merge.
+define internal <2 x i32> @test3(<2 x i32> %v1, <2 x i32> %v2) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT:    [[X:%.*]] = shufflevector <2 x i32> [[V1:%.*]], <2 x i32> [[V2:%.*]], <2 x i32> <i32 1, i32 0>
+; CHECK-NEXT:    ret <2 x i32> [[X]]
+;
+  %x = shufflevector <2 x i32> %v1, <2 x i32> %v2, <2 x i32> <i32 1, i32 0>
+  ret <2 x i32> %x
+}
+
+define void @caller(<2 x i32> %v1, <2 x i32> %v2) {
+; CHECK-LABEL: @caller(
+; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @test1(<2 x i32> [[V1:%.*]], <2 x i32> [[V2:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i32> @test1(<2 x i32> [[V1]], <2 x i32> [[V2]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call <2 x i32> @test3(<2 x i32> [[V1]], <2 x i32> [[V2]])
+; CHECK-NEXT:    ret void
+;
+  call <2 x i32> @test1(<2 x i32> %v1, <2 x i32> %v2)
+  call <2 x i32> @test2(<2 x i32> %v1, <2 x i32> %v2)
+  call <2 x i32> @test3(<2 x i32> %v1, <2 x i32> %v2)
+  ret void
+}
Index: lib/Transforms/Utils/FunctionComparator.cpp
===================================================================
--- lib/Transforms/Utils/FunctionComparator.cpp
+++ lib/Transforms/Utils/FunctionComparator.cpp
@@ -656,6 +656,16 @@
     return cmpNumbers(RMWI->getSyncScopeID(),
                       cast<AtomicRMWInst>(R)->getSyncScopeID());
   }
+  if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(L)) {
+    ArrayRef<int> LMask = SVI->getShuffleMask();
+    ArrayRef<int> RMask = cast<ShuffleVectorInst>(R)->getShuffleMask();
+    if (int Res = cmpNumbers(LMask.size(), RMask.size()))
+      return Res;
+    for (size_t i = 0, e = LMask.size(); i != e; ++i) {
+      if (int Res = cmpNumbers(LMask[i], RMask[i]))
+        return Res;
+    }
+  }
   if (const PHINode *PNL = dyn_cast<PHINode>(L)) {
     const PHINode *PNR = cast<PHINode>(R);
     // Ensure that in addition to the incoming values being identical


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79261.261530.patch
Type: text/x-patch
Size: 2751 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200502/ec4a325c/attachment-0001.bin>


More information about the llvm-commits mailing list