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:
parent
0cc48af0ab
commit
6f50f7841e
@ -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
|
||||
|
40
test/Transforms/MergeFunc/shufflevector.ll
Normal file
40
test/Transforms/MergeFunc/shufflevector.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user