| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 
 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=memcpyopt -S %s -verify-memoryssa | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
define void @test(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[DST2:%.*]], i8 [[C]], i64 128, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %dst2, ptr align 8 %dst1, i64 128, i1 false)
  ret void
}
define void @test_smaller_memcpy(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_smaller_memcpy(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 100, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 100, i1 false)
  ret void
}
define void @test_smaller_memset(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_smaller_memset(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 100, i1 false)
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[DST1]], i64 128, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 100, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 128, i1 false)
  ret void
}
define void @test_align_memset(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_align_memset(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 128, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr align 8 %dst1, i8 %c, i64 128, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 128, i1 false)
  ret void
}
define void @test_different_types(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_different_types(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr [[DST2:%.*]], i8 [[C]], i32 100, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr align 8 %dst1, i8 %c, i64 128, i1 false)
  call void @llvm.memcpy.p0.p0.i32(ptr %dst2, ptr %dst1, i32 100, i1 false)
  ret void
}
define void @test_different_types_2(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_different_types_2(
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr align 8 [[DST1:%.*]], i8 [[C:%.*]], i32 128, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 100, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i32(ptr align 8 %dst1, i8 %c, i32 128, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 100, i1 false)
  ret void
}
define void @test_different_source_gep(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_different_source_gep(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT:    [[P:%.*]] = getelementptr i8, ptr [[DST1]], i64 64
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[P]], i64 64, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
  ; FIXME: We could optimize this as well.
  %p = getelementptr i8, ptr %dst1, i64 64
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %p, i64 64, i1 false)
  ret void
}
define void @test_variable_size_1(ptr %dst1, i64 %dst1_size, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_variable_size_1(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 [[DST1_SIZE:%.*]], i1 false)
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[DST1]], i64 128, i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 %dst1_size, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 128, i1 false)
  ret void
}
define void @test_variable_size_2(ptr %dst1, ptr %dst2, i64 %dst2_size, i8 %c) {
; CHECK-LABEL: @test_variable_size_2(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[DST1]], i64 [[DST2_SIZE:%.*]], i1 false)
; CHECK-NEXT:    ret void
;
  call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 %dst2_size, i1 false)
  ret void
}
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)
declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1)
declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture readonly, i32, i1)
 |