File: strncpy-1.ll

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (199 lines) | stat: -rw-r--r-- 7,130 bytes parent folder | download | duplicates (8)
1
2
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncpy library call simplifier works correctly.
;
; RUN: opt < %s -passes=instcombine -S | FileCheck %s

target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"

@hello = constant [6 x i8] c"hello\00"
@null = constant [1 x i8] zeroinitializer
@null_hello = constant [7 x i8] c"\00hello\00"
@a = common global [32 x i8] zeroinitializer, align 1
@b = common global [32 x i8] zeroinitializer, align 1

declare ptr @strncpy(ptr, ptr, i32)
declare i32 @puts(ptr)

; Check a bunch of strncpy invocations together.

define i32 @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
; CHECK-NEXT:    [[TARGET:%.*]] = alloca [1024 x i8], align 1
; CHECK-NEXT:    store i8 0, ptr [[TARGET]], align 1
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) [[TARGET]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(42) [[TARGET]], i8 0, i32 42, i1 false)
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(42) [[TARGET]], i8 0, i32 42, i1 false)
; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @puts(ptr noundef nonnull dereferenceable(1) [[TARGET]])
; CHECK-NEXT:    ret i32 0
;
  %target = alloca [1024 x i8]
  store i8 0, ptr %target

  %rslt1 = call ptr @strncpy(ptr %target, ptr @hello, i32 6)

  %rslt2 = call ptr @strncpy(ptr %rslt1, ptr @null, i32 42)

  %rslt3 = call ptr @strncpy(ptr %rslt2, ptr @null_hello, i32 42)

  call i32 @puts( ptr %rslt3 )
  ret i32 0
}

; Check strncpy(x, "", y) -> memset(x, '\0', y, 1).

define void @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(32) @a, i8 0, i32 32, i1 false)
; CHECK-NEXT:    ret void
;

  call ptr @strncpy(ptr @a, ptr @null, i32 32)
  ret void
}

; Check strncpy(x, y, 0) -> x.

define ptr @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
; CHECK-NEXT:    ret ptr @a
;

  %ret = call ptr @strncpy(ptr @a, ptr @hello, i32 0)
  ret ptr %ret
}

; Check  strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant].

define void @test_simplify4() {
; CHECK-LABEL: @test_simplify4(
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) @a, ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false)
; CHECK-NEXT:    ret void
;

  call ptr @strncpy(ptr @a, ptr @hello, i32 6)
  ret void
}

define void @test_simplify5(ptr %dst) {
; CHECK-LABEL: @test_simplify5(
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(32) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(32) @str, i32 32, i1 false)
; CHECK-NEXT:    ret void
;
  call ptr @strncpy(ptr dereferenceable(8) %dst, ptr @hello, i32 32)
  ret void
}

define void @test_simplify6(ptr %dst) {
; CHECK-LABEL: @test_simplify6(
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(80) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(32) @str.1, i32 32, i1 false)
; CHECK-NEXT:    ret void
;
  call ptr @strncpy(ptr dereferenceable(80) %dst, ptr @hello, i32 32)
  ret void
}

define void @test_simplify7(ptr %dst, i32 %n) {
; CHECK-LABEL: @test_simplify7(
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr align 1 dereferenceable(80) [[DST:%.*]], i8 0, i32 [[N:%.*]], i1 false)
; CHECK-NEXT:    ret void
;
; Unless N is known to be nonzero, strncpy(D, "", N) need not access any
; bytes in D.
; TODO: The argument, already annotated dereferenceable, should be
; annotated noundef and nonnull by the transformation.  See
; https://reviews.llvm.org/D124633.
  call ptr @strncpy(ptr dereferenceable(80) %dst, ptr @null, i32 %n)
  ret void
}

define ptr @test1(ptr %dst, ptr %src, i32 %n) {
; CHECK-LABEL: @test1(
; CHECK-NEXT:    [[RET:%.*]] = call ptr @strncpy(ptr nonnull [[DST:%.*]], ptr nonnull [[SRC:%.*]], i32 [[N:%.*]])
; CHECK-NEXT:    ret ptr [[RET]]
;
; Unless N is known to be nonzero, strncpy(D, S, N) need not access any
; bytes in either D or S.  Verify that the call isn't annotated with
; the dereferenceable attribute.
; TODO: Both arguments should be annotated noundef in addition to nonnull.
; See https://reviews.llvm.org/D124633.
  %ret = call ptr @strncpy(ptr nonnull %dst, ptr nonnull %src, i32 %n)
  ret ptr %ret
}

define ptr @test2(ptr %dst) {
; CHECK-LABEL: @test2(
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 5, i1 false)
; CHECK-NEXT:    ret ptr [[DST]]
;
  %ret = call ptr @strncpy(ptr nonnull %dst, ptr nonnull @hello, i32 5)
  ret ptr %ret
}

define ptr @test3(ptr %dst, i32 %n) {
; CHECK-LABEL: @test3(
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noalias noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false)
; CHECK-NEXT:    ret ptr [[DST]]
;
  %ret = call ptr @strncpy(ptr noalias nonnull %dst, ptr nonnull @null, i32 5);
  ret ptr %ret
}

define ptr @test4(ptr %dst, i32 %n) {
; CHECK-LABEL: @test4(
; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noalias noundef nonnull align 16 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false)
; CHECK-NEXT:    ret ptr [[DST]]
;
  %ret = call ptr @strncpy(ptr align(16) noalias nonnull %dst, ptr nonnull @null, i32 5);
  ret ptr %ret
}

; Check cases that shouldn't be simplified.

define void @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @strncpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i32 32)
; CHECK-NEXT:    ret void
;

  call ptr @strncpy(ptr @a, ptr @b, i32 32)
  ret void
}

define void @test_no_simplify2() {
; CHECK-LABEL: @test_no_simplify2(
; CHECK-NEXT:    store i64 478560413032, ptr @a, align 1
; CHECK-NEXT:    ret void
;

  call ptr @strncpy(ptr @a, ptr @hello, i32 8)
  ret void
}

define ptr @test_no_simplify3(ptr %dst, ptr %src, i32 %count) {
; CHECK-LABEL: @test_no_simplify3(
; CHECK-NEXT:    [[RET:%.*]] = musttail call ptr @strncpy(ptr [[DST:%.*]], ptr [[SRC:%.*]], i32 32)
; CHECK-NEXT:    ret ptr [[RET]]
;
  %ret = musttail call ptr @strncpy(ptr %dst, ptr %src, i32 32)
  ret ptr %ret
}

define ptr @test_no_simplify4(ptr %dst, ptr %src, i32 %count) {
; CHECK-LABEL: @test_no_simplify4(
; CHECK-NEXT:    [[RET:%.*]] = musttail call ptr @strncpy(ptr [[DST:%.*]], ptr [[SRC:%.*]], i32 6)
; CHECK-NEXT:    ret ptr [[RET]]
;
  %ret = musttail call ptr @strncpy(ptr %dst, ptr %src, i32 6)
  ret ptr %ret
}


define void @test_no_incompatible_attr() {
; CHECK-LABEL: @test_no_incompatible_attr(
; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) @a, ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false)
; CHECK-NEXT:    ret void
;

  call ptr @strncpy(ptr @a, ptr @hello, i32 6)
  ret void
}