1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -basic-aa -dse -S | FileCheck %s 3 4define void @write4to7(i32* nocapture %p) { 5; CHECK-LABEL: @write4to7( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 8; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 9; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 10; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false) 11; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1 12; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4 13; CHECK-NEXT: ret void 14; 15entry: 16 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 17 %p3 = bitcast i32* %arrayidx0 to i8* 18 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false) 19 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1 20 store i32 1, i32* %arrayidx1, align 4 21 ret void 22} 23 24define void @write4to7_weird_element_type(i32* nocapture %p) { 25; CHECK-LABEL: @write4to7_weird_element_type( 26; CHECK-NEXT: entry: 27; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 28; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 29; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4 30; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 31; CHECK-NEXT: call void @llvm.memset.p0i32.i64(i32* align 4 [[TMP2]], i8 0, i64 24, i1 false) 32; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1 33; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4 34; CHECK-NEXT: ret void 35; 36entry: 37 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 38 call void @llvm.memset.p0i32.i64(i32* align 4 %arrayidx0, i8 0, i64 28, i1 false) 39 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1 40 store i32 1, i32* %arrayidx1, align 4 41 ret void 42} 43 44define void @write4to7_addrspace(i32 addrspace(1)* nocapture %p) { 45; CHECK-LABEL: @write4to7_addrspace( 46; CHECK-NEXT: entry: 47; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[P:%.*]], i64 1 48; CHECK-NEXT: [[P3:%.*]] = bitcast i32 addrspace(1)* [[ARRAYIDX0]] to i8 addrspace(1)* 49; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[P3]], i64 4 50; CHECK-NEXT: call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 4 [[TMP0]], i8 0, i64 24, i1 false) 51; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[P]], i64 1 52; CHECK-NEXT: store i32 1, i32 addrspace(1)* [[ARRAYIDX1]], align 4 53; CHECK-NEXT: ret void 54; 55entry: 56 %arrayidx0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 1 57 %p3 = bitcast i32 addrspace(1)* %arrayidx0 to i8 addrspace(1)* 58 call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 4 %p3, i8 0, i64 28, i1 false) 59 %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 1 60 store i32 1, i32 addrspace(1)* %arrayidx1, align 4 61 ret void 62} 63 64define void @write4to7_atomic(i32* nocapture %p) { 65; CHECK-LABEL: @write4to7_atomic( 66; CHECK-NEXT: entry: 67; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 68; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 69; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 70; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4) 71; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1 72; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4 73; CHECK-NEXT: ret void 74; 75entry: 76 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 77 %p3 = bitcast i32* %arrayidx0 to i8* 78 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4) 79 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1 80 store atomic i32 1, i32* %arrayidx1 unordered, align 4 81 ret void 82} 83 84define void @write0to3(i32* nocapture %p) { 85; CHECK-LABEL: @write0to3( 86; CHECK-NEXT: entry: 87; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 88; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 89; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false) 90; CHECK-NEXT: store i32 1, i32* [[P]], align 4 91; CHECK-NEXT: ret void 92; 93entry: 94 %p3 = bitcast i32* %p to i8* 95 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false) 96 store i32 1, i32* %p, align 4 97 ret void 98} 99 100define void @write0to3_atomic(i32* nocapture %p) { 101; CHECK-LABEL: @write0to3_atomic( 102; CHECK-NEXT: entry: 103; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 104; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 105; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4) 106; CHECK-NEXT: store atomic i32 1, i32* [[P]] unordered, align 4 107; CHECK-NEXT: ret void 108; 109entry: 110 %p3 = bitcast i32* %p to i8* 111 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4) 112 store atomic i32 1, i32* %p unordered, align 4 113 ret void 114} 115 116; Atomicity of the store is weaker from the memset 117define void @write0to3_atomic_weaker(i32* nocapture %p) { 118; CHECK-LABEL: @write0to3_atomic_weaker( 119; CHECK-NEXT: entry: 120; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 121; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 122; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4) 123; CHECK-NEXT: store i32 1, i32* [[P]], align 4 124; CHECK-NEXT: ret void 125; 126entry: 127 %p3 = bitcast i32* %p to i8* 128 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4) 129 store i32 1, i32* %p, align 4 130 ret void 131} 132 133define void @write0to7(i32* nocapture %p) { 134; CHECK-LABEL: @write0to7( 135; CHECK-NEXT: entry: 136; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 137; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 8 138; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false) 139; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64* 140; CHECK-NEXT: store i64 1, i64* [[P4]], align 8 141; CHECK-NEXT: ret void 142; 143entry: 144 %p3 = bitcast i32* %p to i8* 145 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false) 146 %p4 = bitcast i32* %p to i64* 147 store i64 1, i64* %p4, align 8 148 ret void 149} 150 151; Changing the memset start and length is okay here because the 152; store is a multiple of the memset element size 153define void @write0to7_atomic(i32* nocapture %p) { 154; CHECK-LABEL: @write0to7_atomic( 155; CHECK-NEXT: entry: 156; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 157; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 8 158; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4) 159; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64* 160; CHECK-NEXT: store atomic i64 1, i64* [[P4]] unordered, align 8 161; CHECK-NEXT: ret void 162; 163entry: 164 %p3 = bitcast i32* %p to i8* 165 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4) 166 %p4 = bitcast i32* %p to i64* 167 store atomic i64 1, i64* %p4 unordered, align 8 168 ret void 169} 170 171define void @write0to7_2(i32* nocapture %p) { 172; CHECK-LABEL: @write0to7_2( 173; CHECK-NEXT: entry: 174; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 175; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 176; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 177; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false) 178; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64* 179; CHECK-NEXT: store i64 1, i64* [[P4]], align 8 180; CHECK-NEXT: ret void 181; 182entry: 183 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 184 %p3 = bitcast i32* %arrayidx0 to i8* 185 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false) 186 %p4 = bitcast i32* %p to i64* 187 store i64 1, i64* %p4, align 8 188 ret void 189} 190 191define void @write0to7_2_atomic(i32* nocapture %p) { 192; CHECK-LABEL: @write0to7_2_atomic( 193; CHECK-NEXT: entry: 194; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 195; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 196; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 197; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4) 198; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64* 199; CHECK-NEXT: store atomic i64 1, i64* [[P4]] unordered, align 8 200; CHECK-NEXT: ret void 201; 202entry: 203 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 204 %p3 = bitcast i32* %arrayidx0 to i8* 205 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4) 206 %p4 = bitcast i32* %p to i64* 207 store atomic i64 1, i64* %p4 unordered, align 8 208 ret void 209} 210 211; We do not trim the beginning of the eariler write if the alignment of the 212; start pointer is changed. 213define void @dontwrite0to3_align8(i32* nocapture %p) { 214; CHECK-LABEL: @dontwrite0to3_align8( 215; CHECK-NEXT: entry: 216; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 217; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i1 false) 218; CHECK-NEXT: store i32 1, i32* [[P]], align 4 219; CHECK-NEXT: ret void 220; 221entry: 222 %p3 = bitcast i32* %p to i8* 223 call void @llvm.memset.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i1 false) 224 store i32 1, i32* %p, align 4 225 ret void 226} 227 228define void @dontwrite0to3_align8_atomic(i32* nocapture %p) { 229; CHECK-LABEL: @dontwrite0to3_align8_atomic( 230; CHECK-NEXT: entry: 231; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 232; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i32 4) 233; CHECK-NEXT: store atomic i32 1, i32* [[P]] unordered, align 4 234; CHECK-NEXT: ret void 235; 236entry: 237 %p3 = bitcast i32* %p to i8* 238 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i32 4) 239 store atomic i32 1, i32* %p unordered, align 4 240 ret void 241} 242 243define void @dontwrite0to1(i32* nocapture %p) { 244; CHECK-LABEL: @dontwrite0to1( 245; CHECK-NEXT: entry: 246; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 247; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i1 false) 248; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16* 249; CHECK-NEXT: store i16 1, i16* [[P4]], align 4 250; CHECK-NEXT: ret void 251; 252entry: 253 %p3 = bitcast i32* %p to i8* 254 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false) 255 %p4 = bitcast i32* %p to i16* 256 store i16 1, i16* %p4, align 4 257 ret void 258} 259 260define void @dontwrite0to1_atomic(i32* nocapture %p) { 261; CHECK-LABEL: @dontwrite0to1_atomic( 262; CHECK-NEXT: entry: 263; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* 264; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4) 265; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16* 266; CHECK-NEXT: store atomic i16 1, i16* [[P4]] unordered, align 4 267; CHECK-NEXT: ret void 268; 269entry: 270 %p3 = bitcast i32* %p to i8* 271 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4) 272 %p4 = bitcast i32* %p to i16* 273 store atomic i16 1, i16* %p4 unordered, align 4 274 ret void 275} 276 277define void @write2to10(i32* nocapture %p) { 278; CHECK-LABEL: @write2to10( 279; CHECK-NEXT: entry: 280; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 281; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 282; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 283; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i1 false) 284; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16* 285; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1 286; CHECK-NEXT: [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64* 287; CHECK-NEXT: store i64 1, i64* [[P5]], align 8 288; CHECK-NEXT: ret void 289; 290entry: 291 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 292 %p3 = bitcast i32* %arrayidx0 to i8* 293 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false) 294 %p4 = bitcast i32* %p to i16* 295 %arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1 296 %p5 = bitcast i16* %arrayidx2 to i64* 297 store i64 1, i64* %p5, align 8 298 ret void 299} 300 301define void @write2to10_atomic(i32* nocapture %p) { 302; CHECK-LABEL: @write2to10_atomic( 303; CHECK-NEXT: entry: 304; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 305; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8* 306; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4 307; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i32 4) 308; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16* 309; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1 310; CHECK-NEXT: [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64* 311; CHECK-NEXT: store atomic i64 1, i64* [[P5]] unordered, align 8 312; CHECK-NEXT: ret void 313; 314entry: 315 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1 316 %p3 = bitcast i32* %arrayidx0 to i8* 317 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4) 318 %p4 = bitcast i32* %p to i16* 319 %arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1 320 %p5 = bitcast i16* %arrayidx2 to i64* 321 store atomic i64 1, i64* %p5 unordered, align 8 322 ret void 323} 324 325define void @write8To15AndThen0To7(i64* nocapture %P) { 326; CHECK-LABEL: @write8To15AndThen0To7( 327; CHECK-NEXT: entry: 328; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8* 329; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0 330; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16 331; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i1 false) 332; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0 333; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1 334; CHECK-NEXT: store i64 1, i64* [[BASE64_1]], align 4 335; CHECK-NEXT: store i64 2, i64* [[BASE64_0]], align 4 336; CHECK-NEXT: ret void 337; 338entry: 339 340 %base0 = bitcast i64* %P to i8* 341 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0 342 tail call void @llvm.memset.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i1 false) 343 344 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0 345 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1 346 347 store i64 1, i64* %base64_1 348 store i64 2, i64* %base64_0 349 ret void 350} 351 352define void @write8To15AndThen0To7_atomic(i64* nocapture %P) { 353; CHECK-LABEL: @write8To15AndThen0To7_atomic( 354; CHECK-NEXT: entry: 355; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8* 356; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0 357; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16 358; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8) 359; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0 360; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1 361; CHECK-NEXT: store atomic i64 1, i64* [[BASE64_1]] unordered, align 8 362; CHECK-NEXT: store atomic i64 2, i64* [[BASE64_0]] unordered, align 8 363; CHECK-NEXT: ret void 364; 365entry: 366 367 %base0 = bitcast i64* %P to i8* 368 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0 369 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8) 370 371 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0 372 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1 373 374 store atomic i64 1, i64* %base64_1 unordered, align 8 375 store atomic i64 2, i64* %base64_0 unordered, align 8 376 ret void 377} 378 379define void @write8To15AndThen0To7_atomic_weaker(i64* nocapture %P) { 380; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker( 381; CHECK-NEXT: entry: 382; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8* 383; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0 384; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16 385; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8) 386; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0 387; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1 388; CHECK-NEXT: store atomic i64 1, i64* [[BASE64_1]] unordered, align 8 389; CHECK-NEXT: store i64 2, i64* [[BASE64_0]], align 8 390; CHECK-NEXT: ret void 391; 392entry: 393 394 %base0 = bitcast i64* %P to i8* 395 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0 396 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8) 397 398 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0 399 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1 400 401 store atomic i64 1, i64* %base64_1 unordered, align 8 402 store i64 2, i64* %base64_0, align 8 403 ret void 404} 405 406define void @write8To15AndThen0To7_atomic_weaker_2(i64* nocapture %P) { 407; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker_2( 408; CHECK-NEXT: entry: 409; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8* 410; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0 411; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16 412; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8) 413; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0 414; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1 415; CHECK-NEXT: store i64 1, i64* [[BASE64_1]], align 8 416; CHECK-NEXT: store atomic i64 2, i64* [[BASE64_0]] unordered, align 8 417; CHECK-NEXT: ret void 418; 419entry: 420 421 %base0 = bitcast i64* %P to i8* 422 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0 423 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8) 424 425 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0 426 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1 427 428 store i64 1, i64* %base64_1, align 8 429 store atomic i64 2, i64* %base64_0 unordered, align 8 430 ret void 431} 432 433declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind 434declare void @llvm.memset.p0i32.i64(i32* nocapture, i8, i64, i1) nounwind 435declare void @llvm.memset.p1i8.i64(i8 addrspace(1)* nocapture, i8, i64, i1) nounwind 436declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind 437 438define void @ow_begin_align1(i8* nocapture %p) { 439; CHECK-LABEL: @ow_begin_align1( 440; CHECK-NEXT: entry: 441; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1 442; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 7 443; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP0]], i8 0, i64 25, i1 false) 444; CHECK-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i64* 445; CHECK-NEXT: store i64 1, i64* [[P2]], align 1 446; CHECK-NEXT: ret void 447; 448entry: 449 %p1 = getelementptr inbounds i8, i8* %p, i64 1 450 call void @llvm.memset.p0i8.i64(i8* align 1 %p1, i8 0, i64 32, i1 false) 451 %p2 = bitcast i8* %p to i64* 452 store i64 1, i64* %p2, align 1 453 ret void 454} 455 456define void @ow_end_align4(i8* nocapture %p) { 457; CHECK-LABEL: @ow_end_align4( 458; CHECK-NEXT: entry: 459; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1 460; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 4 461; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i1 false) 462; CHECK-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i64* 463; CHECK-NEXT: store i64 1, i64* [[P2]], align 1 464; CHECK-NEXT: ret void 465; 466entry: 467 %p1 = getelementptr inbounds i8, i8* %p, i64 1 468 call void @llvm.memset.p0i8.i64(i8* align 4 %p1, i8 0, i64 32, i1 false) 469 %p2 = bitcast i8* %p to i64* 470 store i64 1, i64* %p2, align 1 471 ret void 472} 473 474define void @ow_end_align8(i8* nocapture %p) { 475; CHECK-LABEL: @ow_end_align8( 476; CHECK-NEXT: entry: 477; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1 478; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[P1]], i8 0, i64 32, i1 false) 479; CHECK-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i64* 480; CHECK-NEXT: store i64 1, i64* [[P2]], align 1 481; CHECK-NEXT: ret void 482; 483entry: 484 %p1 = getelementptr inbounds i8, i8* %p, i64 1 485 call void @llvm.memset.p0i8.i64(i8* align 8 %p1, i8 0, i64 32, i1 false) 486 %p2 = bitcast i8* %p to i64* 487 store i64 1, i64* %p2, align 1 488 ret void 489} 490