1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[MergeFuncs] Don't merge shufflevectors with different masks

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.

Differential Revision: https://reviews.llvm.org/D79261
This commit is contained in:
Nikita Popov 2020-05-01 22:28:59 +02:00
parent 0cc48af0ab
commit 6f50f7841e
2 changed files with 50 additions and 0 deletions

View File

@ -656,6 +656,16 @@ int FunctionComparator::cmpOperations(const Instruction *L,
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

View File

@ -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
}