mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 06:35:30 +00:00
[MergeFuncs] Fix bug in merging GetElementPointers
GetElementPointers must have the first argument's type compared for structural equivalence. Previously the code erroneously compared the pointer's type, but this code was dead because all pointer types (of the same address space) are the same. The pointee must be compared instead (using the type stored in the GEP, not from the pointer type which will be erased anyway). Author: jrkoenig Reviewers: dschuff, nlewycky, jfb Subscribers: nlewycky, llvm-commits Differential revision: http://reviews.llvm.org/D12820 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247570 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e50e6f3e3d
commit
85e6f24186
@ -1028,8 +1028,8 @@ int FunctionComparator::cmpGEPs(const GEPOperator *GEPL,
|
||||
if (GEPL->accumulateConstantOffset(DL, OffsetL) &&
|
||||
GEPR->accumulateConstantOffset(DL, OffsetR))
|
||||
return cmpAPInts(OffsetL, OffsetR);
|
||||
if (int Res = cmpTypes(GEPL->getPointerOperand()->getType(),
|
||||
GEPR->getPointerOperand()->getType()))
|
||||
if (int Res = cmpTypes(GEPL->getSourceElementType(),
|
||||
GEPR->getSourceElementType()))
|
||||
return Res;
|
||||
|
||||
if (int Res = cmpNumbers(GEPL->getNumOperands(), GEPR->getNumOperands()))
|
||||
|
46
test/Transforms/MergeFunc/gep-base-type.ll
Normal file
46
test/Transforms/MergeFunc/gep-base-type.ll
Normal file
@ -0,0 +1,46 @@
|
||||
; RUN: opt -mergefunc -S < %s | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
|
||||
; These should not be merged, the type of the GEP pointer argument does not have
|
||||
; the same stride.
|
||||
|
||||
%"struct1" = type <{ i8*, i32, [4 x i8] }>
|
||||
%"struct2" = type { i8*, { i64, i64 } }
|
||||
|
||||
define internal %struct2* @Ffunc(%struct2* %P, i64 %i) {
|
||||
; CHECK-LABEL: @Ffunc(
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: ret
|
||||
%1 = getelementptr inbounds %"struct2", %"struct2"* %P, i64 %i
|
||||
%2 = getelementptr inbounds %"struct2", %"struct2"* %P, i64 %i
|
||||
%3 = getelementptr inbounds %"struct2", %"struct2"* %P, i64 %i
|
||||
%4 = getelementptr inbounds %"struct2", %"struct2"* %P, i64 %i
|
||||
%5 = getelementptr inbounds %"struct2", %"struct2"* %P, i64 %i
|
||||
%6 = getelementptr inbounds %"struct2", %"struct2"* %P, i64 %i
|
||||
ret %struct2* %6
|
||||
}
|
||||
|
||||
|
||||
define internal %struct1* @Gfunc(%struct1* %P, i64 %i) {
|
||||
; CHECK-LABEL: @Gfunc(
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: getelementptr
|
||||
; CHECK-NEXT: ret
|
||||
%1 = getelementptr inbounds %"struct1", %"struct1"* %P, i64 %i
|
||||
%2 = getelementptr inbounds %"struct1", %"struct1"* %P, i64 %i
|
||||
%3 = getelementptr inbounds %"struct1", %"struct1"* %P, i64 %i
|
||||
%4 = getelementptr inbounds %"struct1", %"struct1"* %P, i64 %i
|
||||
%5 = getelementptr inbounds %"struct1", %"struct1"* %P, i64 %i
|
||||
%6 = getelementptr inbounds %"struct1", %"struct1"* %P, i64 %i
|
||||
ret %struct1* %6
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user