204 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=slp-vectorizer -slp-threshold=-200 -mtriple=x86_64-unknown-linux -mcpu=core-avx2 -S | FileCheck %s3 4define void @test_add_sdiv(ptr %arr1, ptr %arr2, i32 %a0, i32 %a1, i32 %a2, i32 %a3) {5; CHECK-LABEL: @test_add_sdiv(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[ARR1:%.*]], align 48; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i32> <i32 0, i32 0, i32 poison, i32 0>, i32 [[A2:%.*]], i32 29; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i32> [[TMP5]], <i32 1, i32 1, i32 42, i32 1>10; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> <i32 poison, i32 poison, i32 0, i32 poison>, i32 [[A0:%.*]], i32 011; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> [[TMP1]], i32 [[A1:%.*]], i32 112; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x i32> [[TMP2]], i32 [[A3:%.*]], i32 313; CHECK-NEXT: [[TMP4:%.*]] = add nsw <4 x i32> <i32 1146, i32 146, i32 0, i32 0>, [[TMP3]]14; CHECK-NEXT: [[TMP8:%.*]] = sdiv <4 x i32> [[TMP0]], [[TMP6]]15; CHECK-NEXT: [[TMP9:%.*]] = add nsw <4 x i32> [[TMP8]], [[TMP4]]16; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr [[ARR3:%.*]], align 417; CHECK-NEXT: ret void18;19entry:20 %gep1.1 = getelementptr i32, ptr %arr1, i32 121 %gep1.2 = getelementptr i32, ptr %arr1, i32 222 %gep1.3 = getelementptr i32, ptr %arr1, i32 323 %gep2.1 = getelementptr i32, ptr %arr2, i32 124 %gep2.2 = getelementptr i32, ptr %arr2, i32 225 %gep2.3 = getelementptr i32, ptr %arr2, i32 326 %v0 = load i32, ptr %arr127 %v1 = load i32, ptr %gep1.128 %v2 = load i32, ptr %gep1.229 %v3 = load i32, ptr %gep1.330 %y0 = add nsw i32 %a0, 114631 %y1 = add nsw i32 %a1, 14632 %y2 = add nsw i32 %a2, 4233 ;; %y3 is zero if %a3 is zero34 %y3 = add nsw i32 %a3, 035 %res0 = add nsw i32 %v0, %y036 %res1 = add nsw i32 %v1, %y137 ;; As such, doing alternate shuffling would be incorrect:38 ;; %vadd = add nsw %v[0-3], %y[0-3]39 ;; %vsdiv = sdiv %v[0-3], %y[0-3]40 ;; %result = shuffle %vadd, %vsdiv, <mask>41 ;; would be illegal.42 %res2 = sdiv i32 %v2, %y243 %res3 = add nsw i32 %v3, %y344 store i32 %res0, ptr %arr245 store i32 %res1, ptr %gep2.146 store i32 %res2, ptr %gep2.247 store i32 %res3, ptr %gep2.348 ret void49}50 51define void @test_add_udiv(ptr %arr1, ptr %arr2, i32 %a0, i32 %a1, i32 %a2, i32 %a3) {52; CHECK-LABEL: @test_add_udiv(53; CHECK-NEXT: entry:54; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[ARR1:%.*]], align 455; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i32> <i32 0, i32 0, i32 poison, i32 0>, i32 [[A2:%.*]], i32 256; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i32> [[TMP5]], <i32 1, i32 1, i32 42, i32 1>57; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> <i32 poison, i32 poison, i32 0, i32 poison>, i32 [[A0:%.*]], i32 058; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> [[TMP1]], i32 [[A1:%.*]], i32 159; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x i32> [[TMP2]], i32 [[A3:%.*]], i32 360; CHECK-NEXT: [[TMP4:%.*]] = add nsw <4 x i32> <i32 1146, i32 146, i32 0, i32 0>, [[TMP3]]61; CHECK-NEXT: [[TMP8:%.*]] = udiv <4 x i32> [[TMP0]], [[TMP6]]62; CHECK-NEXT: [[TMP9:%.*]] = add nsw <4 x i32> [[TMP8]], [[TMP4]]63; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr [[ARR2:%.*]], align 464; CHECK-NEXT: ret void65;66entry:67 %gep1.1 = getelementptr i32, ptr %arr1, i32 168 %gep1.2 = getelementptr i32, ptr %arr1, i32 269 %gep1.3 = getelementptr i32, ptr %arr1, i32 370 %gep2.1 = getelementptr i32, ptr %arr2, i32 171 %gep2.2 = getelementptr i32, ptr %arr2, i32 272 %gep2.3 = getelementptr i32, ptr %arr2, i32 373 %v0 = load i32, ptr %arr174 %v1 = load i32, ptr %gep1.175 %v2 = load i32, ptr %gep1.276 %v3 = load i32, ptr %gep1.377 %y0 = add nsw i32 %a0, 114678 %y1 = add nsw i32 %a1, 14679 %y2 = add nsw i32 %a2, 4280 %y3 = add nsw i32 %a3, 081 %res0 = add nsw i32 %v0, %y082 %res1 = add nsw i32 %v1, %y183 %res2 = udiv i32 %v2, %y284 %res3 = add nsw i32 %v3, %y385 store i32 %res0, ptr %arr286 store i32 %res1, ptr %gep2.187 store i32 %res2, ptr %gep2.288 store i32 %res3, ptr %gep2.389 ret void90}91 92;; Similar test, but now div/rem is main opcode and not the alternate one. Same issue.93define void @test_urem_add(ptr %arr1, ptr %arr2, i32 %a0, i32 %a1, i32 %a2, i32 %a3) {94; CHECK-LABEL: @test_urem_add(95; CHECK-NEXT: entry:96; CHECK-NEXT: [[GEP1_1:%.*]] = getelementptr i32, ptr [[ARR1:%.*]], i32 197; CHECK-NEXT: [[GEP1_2:%.*]] = getelementptr i32, ptr [[ARR1]], i32 298; CHECK-NEXT: [[GEP1_3:%.*]] = getelementptr i32, ptr [[ARR1]], i32 399; CHECK-NEXT: [[GEP2_1:%.*]] = getelementptr i32, ptr [[ARR2:%.*]], i32 1100; CHECK-NEXT: [[GEP2_2:%.*]] = getelementptr i32, ptr [[ARR2]], i32 2101; CHECK-NEXT: [[GEP2_3:%.*]] = getelementptr i32, ptr [[ARR2]], i32 3102; CHECK-NEXT: [[V0:%.*]] = load i32, ptr [[ARR1]], align 4103; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP1_1]], align 4104; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP1_2]], align 4105; CHECK-NEXT: [[V3:%.*]] = load i32, ptr [[GEP1_3]], align 4106; CHECK-NEXT: [[Y0:%.*]] = add nsw i32 [[A0:%.*]], 1146107; CHECK-NEXT: [[Y1:%.*]] = add nsw i32 [[A1:%.*]], 146108; CHECK-NEXT: [[Y2:%.*]] = add nsw i32 [[A2:%.*]], 42109; CHECK-NEXT: [[Y3:%.*]] = add nsw i32 [[A3:%.*]], 0110; CHECK-NEXT: [[RES0:%.*]] = urem i32 [[V0]], [[Y0]]111; CHECK-NEXT: [[RES1:%.*]] = urem i32 [[V1]], [[Y1]]112; CHECK-NEXT: [[RES2:%.*]] = urem i32 [[V2]], [[Y2]]113; CHECK-NEXT: [[RES3:%.*]] = add nsw i32 [[V3]], [[Y3]]114; CHECK-NEXT: store i32 [[RES0]], ptr [[ARR2]], align 4115; CHECK-NEXT: store i32 [[RES1]], ptr [[GEP2_1]], align 4116; CHECK-NEXT: store i32 [[RES2]], ptr [[GEP2_2]], align 4117; CHECK-NEXT: store i32 [[RES3]], ptr [[GEP2_3]], align 4118; CHECK-NEXT: ret void119;120entry:121 %gep1.1 = getelementptr i32, ptr %arr1, i32 1122 %gep1.2 = getelementptr i32, ptr %arr1, i32 2123 %gep1.3 = getelementptr i32, ptr %arr1, i32 3124 %gep2.1 = getelementptr i32, ptr %arr2, i32 1125 %gep2.2 = getelementptr i32, ptr %arr2, i32 2126 %gep2.3 = getelementptr i32, ptr %arr2, i32 3127 %v0 = load i32, ptr %arr1128 %v1 = load i32, ptr %gep1.1129 %v2 = load i32, ptr %gep1.2130 %v3 = load i32, ptr %gep1.3131 %y0 = add nsw i32 %a0, 1146132 %y1 = add nsw i32 %a1, 146133 %y2 = add nsw i32 %a2, 42134 ;; %y3 is zero if %a3 is zero135 %y3 = add nsw i32 %a3, 0136 %res0 = urem i32 %v0, %y0137 %res1 = urem i32 %v1, %y1138 %res2 = urem i32 %v2, %y2139 ;; As such, doing alternate shuffling would be incorrect:140 ;; %vurem = urem %v[0-3], %y[0-3]141 ;; %vadd = add nsw %v[0-3], %y[0-3]142 ;; %result = shuffle %vurem, %vadd, <mask>143 ;; would be illegal.144 %res3 = add nsw i32 %v3, %y3145 store i32 %res0, ptr %arr2146 store i32 %res1, ptr %gep2.1147 store i32 %res2, ptr %gep2.2148 store i32 %res3, ptr %gep2.3149 ret void150}151 152define void @test_srem_add(ptr %arr1, ptr %arr2, i32 %a0, i32 %a1, i32 %a2, i32 %a3) {153; CHECK-LABEL: @test_srem_add(154; CHECK-NEXT: entry:155; CHECK-NEXT: [[GEP1_1:%.*]] = getelementptr i32, ptr [[ARR1:%.*]], i32 1156; CHECK-NEXT: [[GEP1_2:%.*]] = getelementptr i32, ptr [[ARR1]], i32 2157; CHECK-NEXT: [[GEP1_3:%.*]] = getelementptr i32, ptr [[ARR1]], i32 3158; CHECK-NEXT: [[GEP2_1:%.*]] = getelementptr i32, ptr [[ARR2:%.*]], i32 1159; CHECK-NEXT: [[GEP2_2:%.*]] = getelementptr i32, ptr [[ARR2]], i32 2160; CHECK-NEXT: [[GEP2_3:%.*]] = getelementptr i32, ptr [[ARR2]], i32 3161; CHECK-NEXT: [[V0:%.*]] = load i32, ptr [[ARR1]], align 4162; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP1_1]], align 4163; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP1_2]], align 4164; CHECK-NEXT: [[V3:%.*]] = load i32, ptr [[GEP1_3]], align 4165; CHECK-NEXT: [[Y0:%.*]] = add nsw i32 [[A0:%.*]], 1146166; CHECK-NEXT: [[Y1:%.*]] = add nsw i32 [[A1:%.*]], 146167; CHECK-NEXT: [[Y2:%.*]] = add nsw i32 [[A2:%.*]], 42168; CHECK-NEXT: [[Y3:%.*]] = add nsw i32 [[A3:%.*]], 0169; CHECK-NEXT: [[RES0:%.*]] = srem i32 [[V0]], [[Y0]]170; CHECK-NEXT: [[RES1:%.*]] = srem i32 [[V1]], [[Y1]]171; CHECK-NEXT: [[RES2:%.*]] = srem i32 [[V2]], [[Y2]]172; CHECK-NEXT: [[RES3:%.*]] = add nsw i32 [[V3]], [[Y3]]173; CHECK-NEXT: store i32 [[RES0]], ptr [[ARR2]], align 4174; CHECK-NEXT: store i32 [[RES1]], ptr [[GEP2_1]], align 4175; CHECK-NEXT: store i32 [[RES2]], ptr [[GEP2_2]], align 4176; CHECK-NEXT: store i32 [[RES3]], ptr [[GEP2_3]], align 4177; CHECK-NEXT: ret void178;179entry:180 %gep1.1 = getelementptr i32, ptr %arr1, i32 1181 %gep1.2 = getelementptr i32, ptr %arr1, i32 2182 %gep1.3 = getelementptr i32, ptr %arr1, i32 3183 %gep2.1 = getelementptr i32, ptr %arr2, i32 1184 %gep2.2 = getelementptr i32, ptr %arr2, i32 2185 %gep2.3 = getelementptr i32, ptr %arr2, i32 3186 %v0 = load i32, ptr %arr1187 %v1 = load i32, ptr %gep1.1188 %v2 = load i32, ptr %gep1.2189 %v3 = load i32, ptr %gep1.3190 %y0 = add nsw i32 %a0, 1146191 %y1 = add nsw i32 %a1, 146192 %y2 = add nsw i32 %a2, 42193 %y3 = add nsw i32 %a3, 0194 %res0 = srem i32 %v0, %y0195 %res1 = srem i32 %v1, %y1196 %res2 = srem i32 %v2, %y2197 %res3 = add nsw i32 %v3, %y3198 store i32 %res0, ptr %arr2199 store i32 %res1, ptr %gep2.1200 store i32 %res2, ptr %gep2.2201 store i32 %res3, ptr %gep2.3202 ret void203}204