241 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=slp-vectorizer,dce -S -slp-threshold=-100 -slp-vectorize-hor-store | FileCheck %s --check-prefix=GFX93 4@arr = local_unnamed_addr global [32 x i32] zeroinitializer, align 165@arr64 = local_unnamed_addr global [32 x i64] zeroinitializer, align 166@var = global i32 zeroinitializer, align 87@var64 = global i64 zeroinitializer, align 88 9@farr = local_unnamed_addr global [32 x float] zeroinitializer, align 1610@fvar = global float zeroinitializer, align 811 12@darr = local_unnamed_addr global [32 x double] zeroinitializer, align 1613@dvar = global double zeroinitializer, align 814 15; Tests whether the min/max reduction pattern is vectorized if SLP starts at the store.16define i32 @smaxv6() {17; GFX9-LABEL: @smaxv6(18; GFX9-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr @arr, align 1619; GFX9-NEXT: [[TMP2:%.*]] = extractelement <2 x i32> [[TMP1]], i32 020; GFX9-NEXT: [[TMP3:%.*]] = extractelement <2 x i32> [[TMP1]], i32 121; GFX9-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP2]], [[TMP3]]22; GFX9-NEXT: [[SELECT1:%.*]] = select i1 [[CMP1]], i32 [[TMP2]], i32 [[TMP3]]23; GFX9-NEXT: [[TMP4:%.*]] = load <4 x i32>, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 2), align 824; GFX9-NEXT: [[TMP5:%.*]] = call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> [[TMP4]])25; GFX9-NEXT: [[OP_RDX:%.*]] = icmp sgt i32 [[TMP5]], [[SELECT1]]26; GFX9-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i32 [[TMP5]], i32 [[SELECT1]]27; GFX9-NEXT: [[STORE_SELECT:%.*]] = select i1 [[CMP1]], i32 3, i32 428; GFX9-NEXT: store i32 [[STORE_SELECT]], ptr @var, align 829; GFX9-NEXT: ret i32 [[OP_RDX1]]30;31 %load1 = load i32, ptr @arr, align 1632 %load2 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 1), align 433 %cmp1 = icmp sgt i32 %load1, %load234 %select1 = select i1 %cmp1, i32 %load1, i32 %load235 36 %load3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 2), align 837 %cmp2 = icmp sgt i32 %select1, %load338 %select2 = select i1 %cmp2, i32 %select1, i32 %load339 40 %load4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 3), align 441 %cmp3 = icmp sgt i32 %select2, %load442 %select3 = select i1 %cmp3, i32 %select2, i32 %load443 44 %load5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 4), align 1645 %cmp4 = icmp sgt i32 %select3, %load546 %select4 = select i1 %cmp4, i32 %select3, i32 %load547 48 %load6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 5), align 449 %cmp5 = icmp sgt i32 %select4, %load650 %select5 = select i1 %cmp5, i32 %select4, i32 %load651 52 %store-select = select i1 %cmp1, i32 3, i32 453 store i32 %store-select, ptr @var, align 854 ret i32 %select555}56 57define i64 @sminv6() {58; GFX9-LABEL: @sminv6(59; GFX9-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @arr64, align 1660; GFX9-NEXT: [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 061; GFX9-NEXT: [[TMP3:%.*]] = extractelement <2 x i64> [[TMP1]], i32 162; GFX9-NEXT: [[CMP1:%.*]] = icmp slt i64 [[TMP2]], [[TMP3]]63; GFX9-NEXT: [[SELECT1:%.*]] = select i1 [[CMP1]], i64 [[TMP2]], i64 [[TMP3]]64; GFX9-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr getelementptr inbounds ([32 x i64], ptr @arr64, i64 0, i64 2), align 1665; GFX9-NEXT: [[TMP5:%.*]] = call i64 @llvm.vector.reduce.smin.v4i64(<4 x i64> [[TMP4]])66; GFX9-NEXT: [[OP_RDX:%.*]] = icmp slt i64 [[TMP5]], [[SELECT1]]67; GFX9-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i64 [[TMP5]], i64 [[SELECT1]]68; GFX9-NEXT: [[STORE_SELECT:%.*]] = select i1 [[CMP1]], i64 3, i64 469; GFX9-NEXT: store i64 [[STORE_SELECT]], ptr @var64, align 870; GFX9-NEXT: ret i64 [[OP_RDX1]]71;72 %load1 = load i64, ptr @arr64, align 1673 %load2 = load i64, ptr getelementptr inbounds ([32 x i64], ptr @arr64, i64 0, i64 1), align 874 %cmp1 = icmp slt i64 %load1, %load275 %select1 = select i1 %cmp1, i64 %load1, i64 %load276 77 %load3 = load i64, ptr getelementptr inbounds ([32 x i64], ptr @arr64, i64 0, i64 2), align 1678 %cmp2 = icmp slt i64 %select1, %load379 %select2 = select i1 %cmp2, i64 %select1, i64 %load380 81 %load4 = load i64, ptr getelementptr inbounds ([32 x i64], ptr @arr64, i64 0, i64 3), align 882 %cmp3 = icmp slt i64 %select2, %load483 %select3 = select i1 %cmp3, i64 %select2, i64 %load484 85 %load5 = load i64, ptr getelementptr inbounds ([32 x i64], ptr @arr64, i64 0, i64 4), align 1686 %cmp4 = icmp slt i64 %select3, %load587 %select4 = select i1 %cmp4, i64 %select3, i64 %load588 89 %load6 = load i64, ptr getelementptr inbounds ([32 x i64], ptr @arr64, i64 0, i64 5), align 890 %cmp5 = icmp slt i64 %select4, %load691 %select5 = select i1 %cmp5, i64 %select4, i64 %load692 93 %store-select = select i1 %cmp1, i64 3, i64 494 store i64 %store-select, ptr @var64, align 895 ret i64 %select596}97 98; FIXME: Use fmaxnum intrinsics to match what InstCombine creates for fcmp+select99; with fastmath on the select.100define float @fmaxv6() {101; GFX9-LABEL: @fmaxv6(102; GFX9-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr @farr, align 16103; GFX9-NEXT: [[TMP2:%.*]] = extractelement <2 x float> [[TMP1]], i32 0104; GFX9-NEXT: [[TMP3:%.*]] = extractelement <2 x float> [[TMP1]], i32 1105; GFX9-NEXT: [[CMP1:%.*]] = fcmp fast ogt float [[TMP2]], [[TMP3]]106; GFX9-NEXT: [[SELECT1:%.*]] = select i1 [[CMP1]], float [[TMP2]], float [[TMP3]]107; GFX9-NEXT: [[LOAD3:%.*]] = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 2), align 8108; GFX9-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[SELECT1]], [[LOAD3]]109; GFX9-NEXT: [[SELECT2:%.*]] = select i1 [[CMP2]], float [[SELECT1]], float [[LOAD3]]110; GFX9-NEXT: [[LOAD4:%.*]] = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 3), align 4111; GFX9-NEXT: [[CMP3:%.*]] = fcmp fast ogt float [[SELECT2]], [[LOAD4]]112; GFX9-NEXT: [[SELECT3:%.*]] = select i1 [[CMP3]], float [[SELECT2]], float [[LOAD4]]113; GFX9-NEXT: [[LOAD5:%.*]] = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 4), align 16114; GFX9-NEXT: [[CMP4:%.*]] = fcmp fast ogt float [[SELECT3]], [[LOAD5]]115; GFX9-NEXT: [[SELECT4:%.*]] = select i1 [[CMP4]], float [[SELECT3]], float [[LOAD5]]116; GFX9-NEXT: [[LOAD6:%.*]] = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 5), align 4117; GFX9-NEXT: [[CMP5:%.*]] = fcmp fast ogt float [[SELECT4]], [[LOAD6]]118; GFX9-NEXT: [[SELECT5:%.*]] = select i1 [[CMP5]], float [[SELECT4]], float [[LOAD6]]119; GFX9-NEXT: [[STORE_SELECT:%.*]] = select i1 [[CMP1]], float 3.000000e+00, float 4.000000e+00120; GFX9-NEXT: store float [[STORE_SELECT]], ptr @fvar, align 8121; GFX9-NEXT: ret float [[SELECT5]]122;123 %load1 = load float, ptr @farr, align 16124 %load2 = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 1), align 4125 %cmp1 = fcmp fast ogt float %load1, %load2126 %select1 = select i1 %cmp1, float %load1, float %load2127 128 %load3 = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 2), align 8129 %cmp2 = fcmp fast ogt float %select1, %load3130 %select2 = select i1 %cmp2, float %select1, float %load3131 132 %load4 = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 3), align 4133 %cmp3 = fcmp fast ogt float %select2, %load4134 %select3 = select i1 %cmp3, float %select2, float %load4135 136 %load5 = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 4), align 16137 %cmp4 = fcmp fast ogt float %select3, %load5138 %select4 = select i1 %cmp4, float %select3, float %load5139 140 %load6 = load float, ptr getelementptr inbounds ([32 x float], ptr @farr, i64 0, i64 5), align 4141 %cmp5 = fcmp fast ogt float %select4, %load6142 %select5 = select i1 %cmp5, float %select4, float %load6143 144 %store-select = select i1 %cmp1, float 3.0, float 4.0145 store float %store-select, ptr @fvar, align 8146 ret float %select5147}148 149; FIXME: Use fmaxnum intrinsics to match what InstCombine creates for fcmp+select150; with fastmath on the select.151define double @dminv6() {152; GFX9-LABEL: @dminv6(153; GFX9-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr @darr, align 16154; GFX9-NEXT: [[TMP2:%.*]] = extractelement <2 x double> [[TMP1]], i32 0155; GFX9-NEXT: [[TMP3:%.*]] = extractelement <2 x double> [[TMP1]], i32 1156; GFX9-NEXT: [[CMP1:%.*]] = fcmp fast olt double [[TMP2]], [[TMP3]]157; GFX9-NEXT: [[SELECT1:%.*]] = select i1 [[CMP1]], double [[TMP2]], double [[TMP3]]158; GFX9-NEXT: [[LOAD3:%.*]] = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 2), align 8159; GFX9-NEXT: [[CMP2:%.*]] = fcmp fast olt double [[SELECT1]], [[LOAD3]]160; GFX9-NEXT: [[SELECT2:%.*]] = select i1 [[CMP2]], double [[SELECT1]], double [[LOAD3]]161; GFX9-NEXT: [[LOAD4:%.*]] = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 3), align 4162; GFX9-NEXT: [[CMP3:%.*]] = fcmp fast olt double [[SELECT2]], [[LOAD4]]163; GFX9-NEXT: [[SELECT3:%.*]] = select i1 [[CMP3]], double [[SELECT2]], double [[LOAD4]]164; GFX9-NEXT: [[LOAD5:%.*]] = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 4), align 16165; GFX9-NEXT: [[CMP4:%.*]] = fcmp fast olt double [[SELECT3]], [[LOAD5]]166; GFX9-NEXT: [[SELECT4:%.*]] = select i1 [[CMP4]], double [[SELECT3]], double [[LOAD5]]167; GFX9-NEXT: [[LOAD6:%.*]] = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 5), align 4168; GFX9-NEXT: [[CMP5:%.*]] = fcmp fast olt double [[SELECT4]], [[LOAD6]]169; GFX9-NEXT: [[SELECT5:%.*]] = select i1 [[CMP5]], double [[SELECT4]], double [[LOAD6]]170; GFX9-NEXT: [[STORE_SELECT:%.*]] = select i1 [[CMP1]], double 3.000000e+00, double 4.000000e+00171; GFX9-NEXT: store double [[STORE_SELECT]], ptr @dvar, align 8172; GFX9-NEXT: ret double [[SELECT5]]173;174 %load1 = load double, ptr @darr, align 16175 %load2 = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 1), align 4176 %cmp1 = fcmp fast olt double %load1, %load2177 %select1 = select i1 %cmp1, double %load1, double %load2178 179 %load3 = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 2), align 8180 %cmp2 = fcmp fast olt double %select1, %load3181 %select2 = select i1 %cmp2, double %select1, double %load3182 183 %load4 = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 3), align 4184 %cmp3 = fcmp fast olt double %select2, %load4185 %select3 = select i1 %cmp3, double %select2, double %load4186 187 %load5 = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 4), align 16188 %cmp4 = fcmp fast olt double %select3, %load5189 %select4 = select i1 %cmp4, double %select3, double %load5190 191 %load6 = load double, ptr getelementptr inbounds ([32 x double], ptr @darr, i64 0, i64 5), align 4192 %cmp5 = fcmp fast olt double %select4, %load6193 %select5 = select i1 %cmp5, double %select4, double %load6194 195 %store-select = select i1 %cmp1, double 3.0, double 4.0196 store double %store-select, ptr @dvar, align 8197 ret double %select5198}199 200define i32 @smax_wdiff_valuenum(i32, i32 %v1) {201; GFX9-LABEL: @smax_wdiff_valuenum(202; GFX9-NEXT: [[VLOAD:%.*]] = load <2 x i32>, ptr @arr, align 16203; GFX9-NEXT: [[ELT1:%.*]] = extractelement <2 x i32> [[VLOAD]], i32 0204; GFX9-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[ELT1]], [[V1:%.*]]205; GFX9-NEXT: [[EX0:%.*]] = extractelement <2 x i32> [[VLOAD]], i32 0206; GFX9-NEXT: [[SELECT1:%.*]] = select i1 [[CMP1]], i32 [[EX0]], i32 [[V1]]207; GFX9-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 2), align 8208; GFX9-NEXT: [[TMP3:%.*]] = call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> [[TMP2]])209; GFX9-NEXT: [[OP_RDX:%.*]] = icmp sgt i32 [[TMP3]], [[SELECT1]]210; GFX9-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i32 [[TMP3]], i32 [[SELECT1]]211; GFX9-NEXT: [[STOREVAL:%.*]] = select i1 [[CMP1]], i32 3, i32 4212; GFX9-NEXT: store i32 [[STOREVAL]], ptr @var, align 8213; GFX9-NEXT: ret i32 [[OP_RDX1]]214;215 %vload = load <2 x i32>, ptr @arr, align 16216 %elt1 = extractelement <2 x i32> %vload, i32 0217 %cmp1 = icmp sgt i32 %elt1, %v1218 %ex0 = extractelement <2 x i32> %vload, i32 0219 %select1 = select i1 %cmp1, i32 %ex0, i32 %v1220 221 %load3 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 2), align 8222 %cmp2 = icmp sgt i32 %select1, %load3223 %select2 = select i1 %cmp2, i32 %select1, i32 %load3224 225 %load4 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 3), align 4226 %cmp3 = icmp sgt i32 %select2, %load4227 %select3 = select i1 %cmp3, i32 %select2, i32 %load4228 229 %load5 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 4), align 16230 %cmp4 = icmp sgt i32 %select3, %load5231 %select4 = select i1 %cmp4, i32 %select3, i32 %load5232 233 %load6 = load i32, ptr getelementptr inbounds ([32 x i32], ptr @arr, i64 0, i64 5), align 4234 %cmp5 = icmp sgt i32 %select4, %load6235 %select5 = select i1 %cmp5, i32 %select4, i32 %load6236 237 %storeval = select i1 %cmp1, i32 3, i32 4238 store i32 %storeval, ptr @var, align 8239 ret i32 %select5240}241