llvm/llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -O3 -S                                        | FileCheck %s
; RUN: opt < %s -passes='default<O3>' -S | FileCheck %s

; This is based on the following most basic C++ code:
;
; struct S {
;     int* data;
;     int x, y, z;
; };
;
; S gen(S a) {
;     S b;
;     b.data = a.data;
;     return b;
; }
;
; void escape0(S);
;
; int* foo(S a) {
;     S b = gen(a);
;     escape0(b);
;     return b.data;
; }
;
; int cond();
; void sync0();
; void sync1();
; void escape0(int*);
; void escape1(int*);
;
; int* bar(S a) {
;     S b = gen(a);
;     if(cond()) {
;         sync0();
;         escape0(b.data);
;     } else {
;         sync1();
;         escape1(b.data);
;     }
;     return b.data;
; }
;
; There are no inttoptr casts in the original source code, nor should there be any in the optimized IR.

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

%0 = type { ptr, i32, i32, i32 }

define dso_local void @_Z3gen1S(ptr noalias sret(%0) align 8 %arg, ptr byval(%0) align 8 %arg1) {
; CHECK-LABEL: @_Z3gen1S(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I2:%.*]] = load ptr, ptr [[ARG1:%.*]], align 8
; CHECK-NEXT:    store ptr [[I2]], ptr [[ARG:%.*]], align 8
; CHECK-NEXT:    ret void
;
bb:
  %i2 = load ptr, ptr %arg1, align 8
  store ptr %i2, ptr %arg, align 8
  ret void
}

define dso_local ptr @_Z3foo1S(ptr byval(%0) align 8 %arg) {
; CHECK-LABEL: @_Z3foo1S(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I2:%.*]] = alloca [[TMP0:%.*]], align 8
; CHECK-NEXT:    [[I1_SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
; CHECK-NEXT:    store ptr [[I1_SROA_0_0_COPYLOAD]], ptr [[I2]], align 8
; CHECK-NEXT:    tail call void @_Z7escape01S(ptr nonnull byval([[TMP0]]) align 8 [[I2]])
; CHECK-NEXT:    ret ptr [[I1_SROA_0_0_COPYLOAD]]
;
bb:
  %i = alloca %0, align 8
  %i1 = alloca %0, align 8
  %i2 = alloca %0, align 8
  call void @llvm.lifetime.start.p0(i64 24, ptr %i)
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %i1, ptr align 8 %arg, i64 24, i1 false)
  call void @_Z3gen1S(ptr sret(%0) align 8 %i, ptr byval(%0) align 8 %i1)
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %i2, ptr align 8 %i, i64 24, i1 false)
  call void @_Z7escape01S(ptr byval(%0) align 8 %i2)
  %i9 = load ptr, ptr %i, align 8
  call void @llvm.lifetime.end.p0(i64 24, ptr %i)
  ret ptr %i9
}

declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)

declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)

declare dso_local void @_Z7escape01S(ptr byval(%0) align 8)

declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)

define dso_local ptr @_Z3bar1S(ptr byval(%0) align 8 %arg) {
; CHECK-LABEL: @_Z3bar1S(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[I1_SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
; CHECK-NEXT:    [[I5:%.*]] = tail call i32 @_Z4condv()
; CHECK-NEXT:    [[I6_NOT:%.*]] = icmp eq i32 [[I5]], 0
; CHECK-NEXT:    br i1 [[I6_NOT]], label [[BB10:%.*]], label [[BB7:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    tail call void @_Z5sync0v()
; CHECK-NEXT:    tail call void @_Z7escape0Pi(ptr [[I1_SROA_0_0_COPYLOAD]])
; CHECK-NEXT:    br label [[BB13:%.*]]
; CHECK:       bb10:
; CHECK-NEXT:    tail call void @_Z5sync1v()
; CHECK-NEXT:    tail call void @_Z7escape1Pi(ptr [[I1_SROA_0_0_COPYLOAD]])
; CHECK-NEXT:    br label [[BB13]]
; CHECK:       bb13:
; CHECK-NEXT:    ret ptr [[I1_SROA_0_0_COPYLOAD]]
;
bb:
  %i = alloca %0, align 8
  %i1 = alloca %0, align 8
  call void @llvm.lifetime.start.p0(i64 24, ptr %i)
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %i1, ptr align 8 %arg, i64 24, i1 false)
  call void @_Z3gen1S(ptr sret(%0) align 8 %i, ptr byval(%0) align 8 %i1)
  %i5 = call i32 @_Z4condv()
  %i6 = icmp ne i32 %i5, 0
  br i1 %i6, label %bb7, label %bb10

bb7:
  call void @_Z5sync0v()
  %i9 = load ptr, ptr %i, align 8
  call void @_Z7escape0Pi(ptr %i9)
  br label %bb13

bb10:
  call void @_Z5sync1v()
  %i12 = load ptr, ptr %i, align 8
  call void @_Z7escape1Pi(ptr %i12)
  br label %bb13

bb13:
  %i15 = load ptr, ptr %i, align 8
  call void @llvm.lifetime.end.p0(i64 24, ptr %i)
  ret ptr %i15
}

declare dso_local i32 @_Z4condv()
declare dso_local void @_Z5sync0v()
declare dso_local void @_Z7escape0Pi(ptr)
declare dso_local void @_Z5sync1v()
declare dso_local void @_Z7escape1Pi(ptr)