forked from OSchip/llvm-project
[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
ff6a0b6a8e
commit
60e9ee16b4
|
@ -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
|
||||
|
|
|
@ -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