[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:
JF Bastien 2015-09-14 15:37:48 +00:00
parent e50e6f3e3d
commit 85e6f24186
2 changed files with 48 additions and 2 deletions

View File

@ -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()))

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