Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1948,25 +1948,6 @@ return new AddrSpaceCastInst(Operand, GEP.getType()); return new BitCastInst(Operand, GEP.getType()); } - - // Otherwise, if the offset is non-zero, we need to find out if there is a - // field at Offset in 'A's type. If so, we can pull the cast through the - // GEP. - SmallVector NewIndices; - if (FindElementAtOffset(OpType, Offset.getSExtValue(), NewIndices)) { - Value *NGEP = - GEP.isInBounds() - ? Builder.CreateInBoundsGEP(nullptr, Operand, NewIndices) - : Builder.CreateGEP(nullptr, Operand, NewIndices); - - if (NGEP->getType() == GEP.getType()) - return replaceInstUsesWith(GEP, NGEP); - NGEP->takeName(&GEP); - - if (NGEP->getType()->getPointerAddressSpace() != GEP.getAddressSpace()) - return new AddrSpaceCastInst(NGEP, GEP.getType()); - return new BitCastInst(NGEP, GEP.getType()); - } } } Index: test/Transforms/InstCombine/element-atomic-memcpy-to-loads.ll =================================================================== --- test/Transforms/InstCombine/element-atomic-memcpy-to-loads.ll +++ test/Transforms/InstCombine/element-atomic-memcpy-to-loads.ll @@ -13,14 +13,14 @@ ; CHECK-DAG: [[VAL1:%[^\s]+]] = load atomic i32, i32* %memcpy_unfold.src_casted unordered, align 4 ; CHECK-DAG: store atomic i32 [[VAL1]], i32* %memcpy_unfold.dst_casted unordered, align 8 -; CHECK-DAG: [[VAL2:%[^\s]+]] = load atomic i32, i32* %{{[^\s]+}} unordered, align 4 -; CHECK-DAG: store atomic i32 [[VAL2]], i32* %{{[^\s]+}} unordered, align 4 +; CHECK-DAG: [[VAL2:%[^\s]+]] = load atomic i32, i32* %memcpy_unfold.src_addr1 unordered, align 4 +; CHECK-DAG: store atomic i32 [[VAL2]], i32* %memcpy_unfold.dst_addr2 unordered, align 4 -; CHECK-DAG: [[VAL3:%[^\s]+]] = load atomic i32, i32* %{{[^\s]+}} unordered, align 4 -; CHECK-DAG: store atomic i32 [[VAL3]], i32* %{{[^\s]+}} unordered, align 4 +; CHECK-DAG: [[VAL3:%[^\s]+]] = load atomic i32, i32* %memcpy_unfold.src_addr4 unordered, align 4 +; CHECK-DAG: store atomic i32 [[VAL3]], i32* %memcpy_unfold.dst_addr5 unordered, align 4 -; CHECK-DAG: [[VAL4:%[^\s]+]] = load atomic i32, i32* %{{[^\s]+}} unordered, align 4 -; CHECK-DAG: store atomic i32 [[VAL4]], i32* %{{[^\s]+}} unordered, align 4 +; CHECK-DAG: [[VAL4:%[^\s]+]] = load atomic i32, i32* %memcpy_unfold.src_addr7 unordered, align 4 +; CHECK-DAG: store atomic i32 [[VAL4]], i32* %memcpy_unfold.dst_addr8 unordered, align 4 entry: call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i32(i8* align 8 %Dst, i8* align 4 %Src, i32 16, i32 4) ret void Index: test/Transforms/InstCombine/gep-flatten.ll =================================================================== --- test/Transforms/InstCombine/gep-flatten.ll +++ test/Transforms/InstCombine/gep-flatten.ll @@ -0,0 +1,41 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +; CHECK-LABEL: @foo +; CHECK: %2 = call i8* @malloc(i64 808) +; CHECK-NEXT: %.cast = bitcast i8* %2 to %struct.ABC* +; CHECK-NEXT: call void @Setup(%struct.ABC* %.cast) +; CHECK-NEXT: %.cast1 = bitcast i8* %2 to %struct.ABC* +; CHECK-NEXT: %3 = getelementptr inbounds %struct.ABC, %struct.ABC* %.cast1, i64 0, i32 2, i32 0 +; CHECK-NEXT: %4 = load i32, i32* %3, align 4 +; CHECK-NEXT: %.cast2 = bitcast i8* %2 to %struct.ABC* +; CHECK-NEXT: %5 = getelementptr inbounds %struct.ABC, %struct.ABC* %.cast2, i64 0, i32 2, i32 1, i64 33 + +%struct.ABC = type { i32, [100 x i32], %struct.XYZ } +%struct.XYZ = type { i32, [100 x i32] } + +; Function Attrs: noinline nounwind optnone uwtable +define i32 @foo(i32) { + %2 = alloca i32, align 4 + %3 = alloca %struct.ABC*, align 8 + store i32 %0, i32* %2, align 4 + %4 = call i8* @malloc(i64 808) + %5 = bitcast i8* %4 to %struct.ABC* + store %struct.ABC* %5, %struct.ABC** %3, align 8 + %6 = load %struct.ABC*, %struct.ABC** %3, align 8 + call void @Setup(%struct.ABC* %6) + %7 = load %struct.ABC*, %struct.ABC** %3, align 8 + %8 = getelementptr inbounds %struct.ABC, %struct.ABC* %7, i32 0, i32 2 + %9 = getelementptr inbounds %struct.XYZ, %struct.XYZ* %8, i32 0, i32 0 + %10 = load i32, i32* %9, align 4 + %11 = load %struct.ABC*, %struct.ABC** %3, align 8 + %12 = getelementptr inbounds %struct.ABC, %struct.ABC* %11, i32 0, i32 2 + %13 = getelementptr inbounds %struct.XYZ, %struct.XYZ* %12, i32 0, i32 1 + %14 = getelementptr inbounds [100 x i32], [100 x i32]* %13, i64 0, i64 33 + %15 = load i32, i32* %14, align 4 + %16 = add nsw i32 %10, %15 + ret i32 %16 +} + +declare i8* @malloc(i64) + +declare void @Setup(%struct.ABC*) + Index: test/Transforms/InstCombine/getelementptr.ll =================================================================== --- test/Transforms/InstCombine/getelementptr.ll +++ test/Transforms/InstCombine/getelementptr.ll @@ -541,7 +541,7 @@ %G = load i8*, i8** %F ret i8* %G ; CHECK-LABEL: @test32( -; CHECK: %D = getelementptr inbounds [4 x i8*], [4 x i8*]* %A, i64 0, i64 1 +; CHECK: %D = getelementptr inbounds { [16 x i8] }, { [16 x i8] }* %C, i64 0, i32 0, i64 8 ; CHECK: %F = getelementptr inbounds [4 x i8*], [4 x i8*]* %A, i64 0, i64 2 } @@ -551,7 +551,7 @@ define i32* @test33(%struct.Key* %A) { ; CHECK-LABEL: @test33( -; CHECK: getelementptr %struct.Key, %struct.Key* %A, i64 0, i32 0, i32 1 +; CHECK: getelementptr %struct.anon, %struct.anon* %B, i64 0, i32 2 %B = bitcast %struct.Key* %A to %struct.anon* %C = getelementptr %struct.anon, %struct.anon* %B, i32 0, i32 2 ret i32* %C @@ -559,7 +559,7 @@ define i32 addrspace(1)* @test33_as1(%struct.Key addrspace(1)* %A) { ; CHECK-LABEL: @test33_as1( -; CHECK: getelementptr %struct.Key, %struct.Key addrspace(1)* %A, i16 0, i32 0, i32 1 +; CHECK: getelementptr %struct.anon, %struct.anon addrspace(1)* %B, i16 0, i32 2 %B = bitcast %struct.Key addrspace(1)* %A to %struct.anon addrspace(1)* %C = getelementptr %struct.anon, %struct.anon addrspace(1)* %B, i32 0, i32 2 ret i32 addrspace(1)* %C @@ -576,7 +576,7 @@ ; Make sure the GEP indices use the right pointer sized integer define i32 addrspace(1)* @test33_array_struct_as1([10 x %struct.Key] addrspace(1)* %A) { ; CHECK-LABEL: @test33_array_struct_as1( -; CHECK: getelementptr [10 x %struct.Key], [10 x %struct.Key] addrspace(1)* %A, i16 0, i16 1, i32 0, i32 0 +; CHECK: getelementptr [20 x i32], [20 x i32] addrspace(1)* %B, i16 0, i16 2 %B = bitcast [10 x %struct.Key] addrspace(1)* %A to [20 x i32] addrspace(1)* %C = getelementptr [20 x i32], [20 x i32] addrspace(1)* %B, i32 0, i32 2 ret i32 addrspace(1)* %C @@ -584,8 +584,9 @@ define i32 addrspace(1)* @test33_addrspacecast(%struct.Key* %A) { ; CHECK-LABEL: @test33_addrspacecast( -; CHECK: %C = getelementptr %struct.Key, %struct.Key* %A, i64 0, i32 0, i32 1 -; CHECK-NEXT: addrspacecast i32* %C to i32 addrspace(1)* +; CHECK: %1 = bitcast %struct.Key* %A to %struct.anon* +; CHECK-NEXT: %B = addrspacecast %struct.anon* %1 to %struct.anon addrspace(1)* +; CHECK-NEXT: %C = getelementptr %struct.anon, %struct.anon addrspace(1)* %B, i16 0, i32 2 ; CHECK-NEXT: ret %B = addrspacecast %struct.Key* %A to %struct.anon addrspace(1)* %C = getelementptr %struct.anon, %struct.anon addrspace(1)* %B, i32 0, i32 2 Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -897,8 +897,9 @@ define i1 @test59(i8* %foo) { ; CHECK-LABEL: @test59( -; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8* %foo, i64 8 -; CHECK-NEXT: [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64 +; CHECK-NEXT: %bit = bitcast i8* %foo to i32* +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32* %bit, i64 2 +; CHECK-NEXT: [[USE:%.*]] = ptrtoint i32* [[GEP1]] to i64 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]]) ; CHECK-NEXT: ret i1 true ; @@ -914,8 +915,9 @@ define i1 @test59_as1(i8 addrspace(1)* %foo) { ; CHECK-LABEL: @test59_as1( -; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 8 -; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16 +; CHECK-NEXT: %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 2 +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i32 addrspace(1)* [[GEP1]] to i16 ; CHECK-NEXT: [[USE:%.*]] = zext i16 [[TMP1]] to i64 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]]) ; CHECK-NEXT: ret i1 true