| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| |
| ; RUN: opt -mtriple=riscv64 -mattr=+m,+v -passes=slp-vectorizer -S -slp-enable-strided-stores -slp-threshold=-100 -slp-revec < %s | FileCheck %s |
| |
| define void @runtime_stride(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP2]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 %stride |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_complex_scev(ptr %pl, ptr %ps, i64 %stride, i64 %stride1) { |
| ; CHECK-LABEL: define void @runtime_stride_complex_scev( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]], i64 [[STRIDE1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_SS0:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS1:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS2:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS3:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS4:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS5:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS6:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_SS7:%.*]] = getelementptr i8, ptr [[GEP_S7]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP2]], ptr [[GEP_SS0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_SS1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_SS2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_SS3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_SS4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_SS5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_SS6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_SS7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 %stride |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| %gep_ss0 = getelementptr i8, ptr %gep_s0, i64 %stride1 |
| %gep_ss1 = getelementptr i8, ptr %gep_s1, i64 %stride1 |
| %gep_ss2 = getelementptr i8, ptr %gep_s2, i64 %stride1 |
| %gep_ss3 = getelementptr i8, ptr %gep_s3, i64 %stride1 |
| %gep_ss4 = getelementptr i8, ptr %gep_s4, i64 %stride1 |
| %gep_ss5 = getelementptr i8, ptr %gep_s5, i64 %stride1 |
| %gep_ss6 = getelementptr i8, ptr %gep_s6, i64 %stride1 |
| %gep_ss7 = getelementptr i8, ptr %gep_s7, i64 %stride1 |
| |
| store i8 %load0, ptr %gep_ss0 |
| store i8 %load1, ptr %gep_ss1 |
| store i8 %load2, ptr %gep_ss2 |
| store i8 %load3, ptr %gep_ss3 |
| store i8 %load4, ptr %gep_ss4 |
| store i8 %load5, ptr %gep_ss5 |
| store i8 %load6, ptr %gep_ss6 |
| store i8 %load7, ptr %gep_ss7 |
| |
| ret void |
| } |
| |
| define void @two_runtime_strides(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @two_runtime_strides( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[PS1:%.*]] = mul i64 [[STRIDE]], 16 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[PS]], i64 [[PS1]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP2]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %ps1 = mul i64 %stride, 16 |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %ps, i64 %ps1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @runtime_strides_constant_gap(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_strides_constant_gap( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[PS]], i64 100 |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP2]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %ps, i64 100 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @overlapping_strides(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @overlapping_strides( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[STRIDE2:%.*]] = mul i64 [[STRIDE]], 1 |
| ; CHECK-NEXT: [[STRIDE1:%.*]] = mul i64 [[STRIDE]], 2 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE2]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE2]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE2]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[PS]], i64 [[STRIDE1]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE2]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE2]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE2]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP2]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %stride1 = mul i64 %stride, 1 |
| %ps1 = mul i64 %stride, 2 |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride1 |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride1 |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride1 |
| %gep_s4 = getelementptr i8, ptr %ps, i64 %ps1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride1 |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride1 |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride1 |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_unit_stride(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride_unit_stride( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[LOAD7:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = call <8 x i8> @llvm.masked.load.v8i8.p0(ptr align 1 [[GEP_L0]], <8 x i1> <i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 true>, <8 x i8> poison) |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 7> |
| ; CHECK-NEXT: [[LOAD2:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 1 |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 1 |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 1 |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i8> [[TMP2]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[LOAD2]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[LOAD7]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 1 |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 1 |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 1 |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @unit_stride_runtime_stride(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @unit_stride_runtime_stride( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i8>, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 1 |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 1 |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 1 |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 1 |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i8> [[TMP2]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 1 |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 1 |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 1 |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_constant_stride(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride_constant_stride( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i8>, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: call void @llvm.experimental.vp.strided.store.v4i8.p0.i64(<4 x i8> [[TMP3]], ptr align 1 [[GEP_S4]], i64 2, <4 x i1> splat (i1 true), i32 4) |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 2 |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 2 |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 2 |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @constant_stride_runtime_stride(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @constant_stride_runtime_stride( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i8>, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 2 |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 2 |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 2 |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 1 |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: call void @llvm.experimental.vp.strided.store.v4i8.p0.i64(<4 x i8> [[TMP1]], ptr align 1 [[GEP_S0]], i64 2, <4 x i1> splat (i1 true), i32 4) |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i8> [[TMP2]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 2 |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 2 |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 2 |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @overlap(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @overlap( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[LOAD2:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i8> [[TMP2]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[LOAD2]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 1 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 1 |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 1 |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| |
| ret void |
| } |
| |
| define void @overlap_constant_stride(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @overlap_constant_stride( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[LOAD2:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i8> [[TMP2]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[LOAD2]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: call void @llvm.experimental.vp.strided.store.v4i8.p0.i64(<4 x i8> [[TMP1]], ptr align 1 [[GEP_S3]], i64 2, <4 x i1> splat (i1 true), i32 4) |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 2 |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 2 |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 2 |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_reorder(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride_reorder( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP2]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP3]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 7 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 3 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 %stride |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_unschedulable(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride_unschedulable( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L5:%.*]] = getelementptr i8, ptr [[PL]], i64 5 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[GEP_L5]], align 1 |
| ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP10:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[GEP_L1]], align 1 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <8 x i8> [[TMP1]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP5]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP10]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP6]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP11]], ptr [[GEP_S5]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S1]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 %stride |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i8 %load1, ptr %gep_s6 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i8 %load5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s1 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_revec(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride_revec( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[GEP_L0]], align 4 |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[PS]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> |
| ; CHECK-NEXT: store <4 x i8> [[TMP2]], ptr [[GEP_S0]], align 4 |
| ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7> |
| ; CHECK-NEXT: store <4 x i8> [[TMP3]], ptr [[GEP_S4]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| |
| %load0 = load <4 x i8>, ptr %gep_l0 |
| %load4 = load <4 x i8>, ptr %gep_l4 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s4 = getelementptr i8, ptr %ps, i64 %stride |
| |
| store <4 x i8> %load0, ptr %gep_s0 |
| store <4 x i8> %load4, ptr %gep_s4 |
| |
| ret void |
| } |
| |
| define void @runtime_stride_diff_types(ptr %pl, ptr %ps, i64 %stride) { |
| ; CHECK-LABEL: define void @runtime_stride_diff_types( |
| ; CHECK-SAME: ptr [[PL:%.*]], ptr [[PS:%.*]], i64 [[STRIDE:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[GEP_L0:%.*]] = getelementptr i8, ptr [[PL]], i64 0 |
| ; CHECK-NEXT: [[GEP_L1:%.*]] = getelementptr i8, ptr [[PL]], i64 1 |
| ; CHECK-NEXT: [[GEP_L2:%.*]] = getelementptr i8, ptr [[PL]], i64 2 |
| ; CHECK-NEXT: [[GEP_L3:%.*]] = getelementptr i8, ptr [[PL]], i64 3 |
| ; CHECK-NEXT: [[GEP_L4:%.*]] = getelementptr i8, ptr [[PL]], i64 4 |
| ; CHECK-NEXT: [[GEP_L6:%.*]] = getelementptr i8, ptr [[PL]], i64 6 |
| ; CHECK-NEXT: [[GEP_L7:%.*]] = getelementptr i8, ptr [[PL]], i64 7 |
| ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr [[GEP_L4]], align 1 |
| ; CHECK-NEXT: [[TMP1:%.*]] = call <5 x i8> @llvm.masked.load.v5i8.p0(ptr align 1 [[GEP_L0]], <5 x i1> <i1 true, i1 false, i1 true, i1 true, i1 true>, <5 x i8> poison) |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <5 x i8> [[TMP1]], <5 x i8> poison, <4 x i32> <i32 0, i32 2, i32 3, i32 4> |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i8, ptr [[GEP_L3]], align 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[GEP_L2]], align 1 |
| ; CHECK-NEXT: [[LOAD6:%.*]] = load i8, ptr [[GEP_L6]], align 1 |
| ; CHECK-NEXT: [[LOAD7:%.*]] = load i8, ptr [[GEP_L7]], align 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = call <2 x i8> @llvm.experimental.vp.strided.load.v2i8.p0.i64(ptr align 1 [[GEP_L1]], i64 4, <2 x i1> splat (i1 true), i32 2) |
| ; CHECK-NEXT: [[GEP_S0:%.*]] = getelementptr i8, ptr [[PS]], i64 0 |
| ; CHECK-NEXT: [[GEP_S1:%.*]] = getelementptr i8, ptr [[GEP_S0]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S2:%.*]] = getelementptr i8, ptr [[GEP_S1]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S3:%.*]] = getelementptr i8, ptr [[GEP_S2]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S4:%.*]] = getelementptr i8, ptr [[GEP_S3]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S5:%.*]] = getelementptr i8, ptr [[GEP_S4]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S6:%.*]] = getelementptr i8, ptr [[GEP_S5]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[GEP_S7:%.*]] = getelementptr i8, ptr [[GEP_S6]], i64 [[STRIDE]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i8> [[TMP2]], i64 0 |
| ; CHECK-NEXT: store i8 [[TMP4]], ptr [[GEP_S0]], align 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i8> [[TMP3]], i64 0 |
| ; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i16 |
| ; CHECK-NEXT: store i16 [[TMP6]], ptr [[GEP_S1]], align 2 |
| ; CHECK-NEXT: store i8 [[TMP7]], ptr [[GEP_S2]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP8]], ptr [[GEP_S3]], align 1 |
| ; CHECK-NEXT: store i8 [[TMP9]], ptr [[GEP_S4]], align 1 |
| ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i8> [[TMP3]], i64 1 |
| ; CHECK-NEXT: [[TMP11:%.*]] = zext i8 [[TMP10]] to i16 |
| ; CHECK-NEXT: store i16 [[TMP11]], ptr [[GEP_S5]], align 2 |
| ; CHECK-NEXT: store i8 [[LOAD6]], ptr [[GEP_S6]], align 1 |
| ; CHECK-NEXT: store i8 [[LOAD7]], ptr [[GEP_S7]], align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %gep_l0 = getelementptr i8, ptr %pl, i64 0 |
| %gep_l1 = getelementptr i8, ptr %pl, i64 1 |
| %gep_l2 = getelementptr i8, ptr %pl, i64 2 |
| %gep_l3 = getelementptr i8, ptr %pl, i64 3 |
| %gep_l4 = getelementptr i8, ptr %pl, i64 4 |
| %gep_l5 = getelementptr i8, ptr %pl, i64 5 |
| %gep_l6 = getelementptr i8, ptr %pl, i64 6 |
| %gep_l7 = getelementptr i8, ptr %pl, i64 7 |
| |
| %load0 = load i8, ptr %gep_l0 |
| %load1 = load i8, ptr %gep_l1 |
| %load2 = load i8, ptr %gep_l2 |
| %load3 = load i8, ptr %gep_l3 |
| %load4 = load i8, ptr %gep_l4 |
| %load5 = load i8, ptr %gep_l5 |
| %load6 = load i8, ptr %gep_l6 |
| %load7 = load i8, ptr %gep_l7 |
| |
| %zext1 = zext i8 %load1 to i16 |
| %zext5 = zext i8 %load5 to i16 |
| |
| %gep_s0 = getelementptr i8, ptr %ps, i64 0 |
| %gep_s1 = getelementptr i8, ptr %gep_s0, i64 %stride |
| %gep_s2 = getelementptr i8, ptr %gep_s1, i64 %stride |
| %gep_s3 = getelementptr i8, ptr %gep_s2, i64 %stride |
| %gep_s4 = getelementptr i8, ptr %gep_s3, i64 %stride |
| %gep_s5 = getelementptr i8, ptr %gep_s4, i64 %stride |
| %gep_s6 = getelementptr i8, ptr %gep_s5, i64 %stride |
| %gep_s7 = getelementptr i8, ptr %gep_s6, i64 %stride |
| |
| store i8 %load0, ptr %gep_s0 |
| store i16 %zext1, ptr %gep_s1 |
| store i8 %load2, ptr %gep_s2 |
| store i8 %load3, ptr %gep_s3 |
| store i8 %load4, ptr %gep_s4 |
| store i16 %zext5, ptr %gep_s5 |
| store i8 %load6, ptr %gep_s6 |
| store i8 %load7, ptr %gep_s7 |
| |
| ret void |
| } |