; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 ; RUN: llc -mtriple aarch64-none-linux-gnu < %s | FileCheck %s ; Verify that hasNearbyPairedStore sees through non-inbounds GEPs ; (as produced by LoopStrengthReduce) and avoids unprofitable ST2 ; lowering in favor of zip+stp. define void @st2_noninbounds_gep(ptr %buf, <8 x i16> %a) { ; CHECK-LABEL: st2_noninbounds_gep: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: movi v1.2d, #0000000000000000 ; CHECK-NEXT: zip1 v2.8h, v0.8h, v1.8h ; CHECK-NEXT: zip2 v0.8h, v0.8h, v1.8h ; CHECK-NEXT: stp q2, q0, [x0] ; CHECK-NEXT: ret entry: %vzip.i = shufflevector <8 x i16> %a, <8 x i16> , <8 x i32> %vzip1.i = shufflevector <8 x i16> %a, <8 x i16> , <8 x i32> store <8 x i16> %vzip.i, ptr %buf, align 4 %add.ptr = getelementptr i32, ptr %buf, i64 4 store <8 x i16> %vzip1.i, ptr %add.ptr, align 4 ret void } ; Same pattern but with a negative non-inbounds offset, mimicking LSR output ; where the base pointer is advanced past the stores and offsets go negative. define void @st2_noninbounds_negative_offset(ptr %buf, <8 x i16> %a) { ; CHECK-LABEL: st2_noninbounds_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: movi v1.2d, #0000000000000000 ; CHECK-NEXT: zip1 v2.8h, v0.8h, v1.8h ; CHECK-NEXT: zip2 v0.8h, v0.8h, v1.8h ; CHECK-NEXT: stp q2, q0, [x0] ; CHECK-NEXT: ret entry: %advanced = getelementptr i8, ptr %buf, i64 32 %vzip.i = shufflevector <8 x i16> %a, <8 x i16> , <8 x i32> %vzip1.i = shufflevector <8 x i16> %a, <8 x i16> , <8 x i32> %ptr0 = getelementptr i8, ptr %advanced, i64 -32 store <8 x i16> %vzip.i, ptr %ptr0, align 4 %ptr1 = getelementptr i8, ptr %advanced, i64 -16 store <8 x i16> %vzip1.i, ptr %ptr1, align 4 ret void }