1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -slp-vectorizer -slp-vectorize-hor -S -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver2 -debug < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,AVX 3; RUN: opt -slp-vectorizer -slp-vectorize-hor -S -mtriple=x86_64-unknown-linux-gnu -mcpu=core2 -debug < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,SSE 4; REQUIRES: asserts 5 6; int test_add(unsigned int *p) { 7; int result = 0; 8; for (int i = 0; i < 8; i++) 9; result += p[i]; 10; return result; 11; } 12 13; Vector cost is 5, Scalar cost is 7 14; AVX: Adding cost -2 for reduction that starts with %7 = load i32, i32* %arrayidx.7, align 4 (It is a splitting reduction) 15; Vector cost is 6, Scalar cost is 7 16; SSE: Adding cost -1 for reduction that starts with %7 = load i32, i32* %arrayidx.7, align 4 (It is a splitting reduction) 17define i32 @test_add(i32* nocapture readonly %p) { 18; CHECK-LABEL: @test_add( 19; CHECK-NEXT: entry: 20; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 21; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 2 22; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 3 23; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 24; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 5 25; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 6 26; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7 27; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[P]] to <8 x i32>* 28; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, <8 x i32>* [[TMP0]], align 4 29; CHECK-NEXT: [[MUL_18:%.*]] = add i32 undef, undef 30; CHECK-NEXT: [[MUL_29:%.*]] = add i32 undef, [[MUL_18]] 31; CHECK-NEXT: [[MUL_310:%.*]] = add i32 undef, [[MUL_29]] 32; CHECK-NEXT: [[MUL_411:%.*]] = add i32 undef, [[MUL_310]] 33; CHECK-NEXT: [[MUL_512:%.*]] = add i32 undef, [[MUL_411]] 34; CHECK-NEXT: [[MUL_613:%.*]] = add i32 undef, [[MUL_512]] 35; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef> 36; CHECK-NEXT: [[BIN_RDX:%.*]] = add <8 x i32> [[TMP1]], [[RDX_SHUF]] 37; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <8 x i32> [[BIN_RDX]], <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 38; CHECK-NEXT: [[BIN_RDX2:%.*]] = add <8 x i32> [[BIN_RDX]], [[RDX_SHUF1]] 39; CHECK-NEXT: [[RDX_SHUF3:%.*]] = shufflevector <8 x i32> [[BIN_RDX2]], <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 40; CHECK-NEXT: [[BIN_RDX4:%.*]] = add <8 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] 41; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i32> [[BIN_RDX4]], i32 0 42; CHECK-NEXT: [[MUL_714:%.*]] = add i32 undef, [[MUL_613]] 43; CHECK-NEXT: ret i32 [[TMP2]] 44; 45entry: 46 %0 = load i32, i32* %p, align 4 47 %arrayidx.1 = getelementptr inbounds i32, i32* %p, i64 1 48 %1 = load i32, i32* %arrayidx.1, align 4 49 %mul.18 = add i32 %1, %0 50 %arrayidx.2 = getelementptr inbounds i32, i32* %p, i64 2 51 %2 = load i32, i32* %arrayidx.2, align 4 52 %mul.29 = add i32 %2, %mul.18 53 %arrayidx.3 = getelementptr inbounds i32, i32* %p, i64 3 54 %3 = load i32, i32* %arrayidx.3, align 4 55 %mul.310 = add i32 %3, %mul.29 56 %arrayidx.4 = getelementptr inbounds i32, i32* %p, i64 4 57 %4 = load i32, i32* %arrayidx.4, align 4 58 %mul.411 = add i32 %4, %mul.310 59 %arrayidx.5 = getelementptr inbounds i32, i32* %p, i64 5 60 %5 = load i32, i32* %arrayidx.5, align 4 61 %mul.512 = add i32 %5, %mul.411 62 %arrayidx.6 = getelementptr inbounds i32, i32* %p, i64 6 63 %6 = load i32, i32* %arrayidx.6, align 4 64 %mul.613 = add i32 %6, %mul.512 65 %arrayidx.7 = getelementptr inbounds i32, i32* %p, i64 7 66 %7 = load i32, i32* %arrayidx.7, align 4 67 %mul.714 = add i32 %7, %mul.613 68 ret i32 %mul.714 69} 70 71; int test_mul(unsigned int *p) { 72; int result = 0; 73; for (int i = 0; i < 8; i++) 74; result *= p[i]; 75; return result; 76; } 77 78define i32 @test_mul(i32* nocapture readonly %p) { 79; CHECK-LABEL: @test_mul( 80; CHECK-NEXT: entry: 81; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[P:%.*]], align 4 82; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1 83; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 84; CHECK-NEXT: [[MUL_18:%.*]] = mul i32 [[TMP1]], [[TMP0]] 85; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 2 86; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 87; CHECK-NEXT: [[MUL_29:%.*]] = mul i32 [[TMP2]], [[MUL_18]] 88; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 3 89; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 90; CHECK-NEXT: [[MUL_310:%.*]] = mul i32 [[TMP3]], [[MUL_29]] 91; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 92; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 93; CHECK-NEXT: [[MUL_411:%.*]] = mul i32 [[TMP4]], [[MUL_310]] 94; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 5 95; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 96; CHECK-NEXT: [[MUL_512:%.*]] = mul i32 [[TMP5]], [[MUL_411]] 97; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 6 98; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 99; CHECK-NEXT: [[MUL_613:%.*]] = mul i32 [[TMP6]], [[MUL_512]] 100; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7 101; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 102; CHECK-NEXT: [[MUL_714:%.*]] = mul i32 [[TMP7]], [[MUL_613]] 103; CHECK-NEXT: ret i32 [[MUL_714]] 104; 105entry: 106 %0 = load i32, i32* %p, align 4 107 %arrayidx.1 = getelementptr inbounds i32, i32* %p, i64 1 108 %1 = load i32, i32* %arrayidx.1, align 4 109 %mul.18 = mul i32 %1, %0 110 %arrayidx.2 = getelementptr inbounds i32, i32* %p, i64 2 111 %2 = load i32, i32* %arrayidx.2, align 4 112 %mul.29 = mul i32 %2, %mul.18 113 %arrayidx.3 = getelementptr inbounds i32, i32* %p, i64 3 114 %3 = load i32, i32* %arrayidx.3, align 4 115 %mul.310 = mul i32 %3, %mul.29 116 %arrayidx.4 = getelementptr inbounds i32, i32* %p, i64 4 117 %4 = load i32, i32* %arrayidx.4, align 4 118 %mul.411 = mul i32 %4, %mul.310 119 %arrayidx.5 = getelementptr inbounds i32, i32* %p, i64 5 120 %5 = load i32, i32* %arrayidx.5, align 4 121 %mul.512 = mul i32 %5, %mul.411 122 %arrayidx.6 = getelementptr inbounds i32, i32* %p, i64 6 123 %6 = load i32, i32* %arrayidx.6, align 4 124 %mul.613 = mul i32 %6, %mul.512 125 %arrayidx.7 = getelementptr inbounds i32, i32* %p, i64 7 126 %7 = load i32, i32* %arrayidx.7, align 4 127 %mul.714 = mul i32 %7, %mul.613 128 ret i32 %mul.714 129} 130 131; int test_and(unsigned int *p) { 132; int result = 0; 133; for (int i = 0; i < 8; i++) 134; result &= p[i]; 135; return result; 136; } 137 138define i32 @test_and(i32* nocapture readonly %p) { 139; CHECK-LABEL: @test_and( 140; CHECK-NEXT: entry: 141; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 142; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 2 143; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 3 144; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 145; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 5 146; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 6 147; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7 148; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[P]] to <8 x i32>* 149; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, <8 x i32>* [[TMP0]], align 4 150; CHECK-NEXT: [[MUL_18:%.*]] = and i32 undef, undef 151; CHECK-NEXT: [[MUL_29:%.*]] = and i32 undef, [[MUL_18]] 152; CHECK-NEXT: [[MUL_310:%.*]] = and i32 undef, [[MUL_29]] 153; CHECK-NEXT: [[MUL_411:%.*]] = and i32 undef, [[MUL_310]] 154; CHECK-NEXT: [[MUL_512:%.*]] = and i32 undef, [[MUL_411]] 155; CHECK-NEXT: [[MUL_613:%.*]] = and i32 undef, [[MUL_512]] 156; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef> 157; CHECK-NEXT: [[BIN_RDX:%.*]] = and <8 x i32> [[TMP1]], [[RDX_SHUF]] 158; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <8 x i32> [[BIN_RDX]], <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 159; CHECK-NEXT: [[BIN_RDX2:%.*]] = and <8 x i32> [[BIN_RDX]], [[RDX_SHUF1]] 160; CHECK-NEXT: [[RDX_SHUF3:%.*]] = shufflevector <8 x i32> [[BIN_RDX2]], <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 161; CHECK-NEXT: [[BIN_RDX4:%.*]] = and <8 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] 162; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i32> [[BIN_RDX4]], i32 0 163; CHECK-NEXT: [[MUL_714:%.*]] = and i32 undef, [[MUL_613]] 164; CHECK-NEXT: ret i32 [[TMP2]] 165; 166entry: 167 %0 = load i32, i32* %p, align 4 168 %arrayidx.1 = getelementptr inbounds i32, i32* %p, i64 1 169 %1 = load i32, i32* %arrayidx.1, align 4 170 %mul.18 = and i32 %1, %0 171 %arrayidx.2 = getelementptr inbounds i32, i32* %p, i64 2 172 %2 = load i32, i32* %arrayidx.2, align 4 173 %mul.29 = and i32 %2, %mul.18 174 %arrayidx.3 = getelementptr inbounds i32, i32* %p, i64 3 175 %3 = load i32, i32* %arrayidx.3, align 4 176 %mul.310 = and i32 %3, %mul.29 177 %arrayidx.4 = getelementptr inbounds i32, i32* %p, i64 4 178 %4 = load i32, i32* %arrayidx.4, align 4 179 %mul.411 = and i32 %4, %mul.310 180 %arrayidx.5 = getelementptr inbounds i32, i32* %p, i64 5 181 %5 = load i32, i32* %arrayidx.5, align 4 182 %mul.512 = and i32 %5, %mul.411 183 %arrayidx.6 = getelementptr inbounds i32, i32* %p, i64 6 184 %6 = load i32, i32* %arrayidx.6, align 4 185 %mul.613 = and i32 %6, %mul.512 186 %arrayidx.7 = getelementptr inbounds i32, i32* %p, i64 7 187 %7 = load i32, i32* %arrayidx.7, align 4 188 %mul.714 = and i32 %7, %mul.613 189 ret i32 %mul.714 190} 191 192; int test_or(unsigned int *p) { 193; int result = 0; 194; for (int i = 0; i < 8; i++) 195; result |= p[i]; 196; return result; 197; } 198 199define i32 @test_or(i32* nocapture readonly %p) { 200; CHECK-LABEL: @test_or( 201; CHECK-NEXT: entry: 202; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 203; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 2 204; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 3 205; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 206; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 5 207; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 6 208; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7 209; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[P]] to <8 x i32>* 210; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, <8 x i32>* [[TMP0]], align 4 211; CHECK-NEXT: [[MUL_18:%.*]] = or i32 undef, undef 212; CHECK-NEXT: [[MUL_29:%.*]] = or i32 undef, [[MUL_18]] 213; CHECK-NEXT: [[MUL_310:%.*]] = or i32 undef, [[MUL_29]] 214; CHECK-NEXT: [[MUL_411:%.*]] = or i32 undef, [[MUL_310]] 215; CHECK-NEXT: [[MUL_512:%.*]] = or i32 undef, [[MUL_411]] 216; CHECK-NEXT: [[MUL_613:%.*]] = or i32 undef, [[MUL_512]] 217; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef> 218; CHECK-NEXT: [[BIN_RDX:%.*]] = or <8 x i32> [[TMP1]], [[RDX_SHUF]] 219; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <8 x i32> [[BIN_RDX]], <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 220; CHECK-NEXT: [[BIN_RDX2:%.*]] = or <8 x i32> [[BIN_RDX]], [[RDX_SHUF1]] 221; CHECK-NEXT: [[RDX_SHUF3:%.*]] = shufflevector <8 x i32> [[BIN_RDX2]], <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 222; CHECK-NEXT: [[BIN_RDX4:%.*]] = or <8 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] 223; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i32> [[BIN_RDX4]], i32 0 224; CHECK-NEXT: [[MUL_714:%.*]] = or i32 undef, [[MUL_613]] 225; CHECK-NEXT: ret i32 [[TMP2]] 226; 227entry: 228 %0 = load i32, i32* %p, align 4 229 %arrayidx.1 = getelementptr inbounds i32, i32* %p, i64 1 230 %1 = load i32, i32* %arrayidx.1, align 4 231 %mul.18 = or i32 %1, %0 232 %arrayidx.2 = getelementptr inbounds i32, i32* %p, i64 2 233 %2 = load i32, i32* %arrayidx.2, align 4 234 %mul.29 = or i32 %2, %mul.18 235 %arrayidx.3 = getelementptr inbounds i32, i32* %p, i64 3 236 %3 = load i32, i32* %arrayidx.3, align 4 237 %mul.310 = or i32 %3, %mul.29 238 %arrayidx.4 = getelementptr inbounds i32, i32* %p, i64 4 239 %4 = load i32, i32* %arrayidx.4, align 4 240 %mul.411 = or i32 %4, %mul.310 241 %arrayidx.5 = getelementptr inbounds i32, i32* %p, i64 5 242 %5 = load i32, i32* %arrayidx.5, align 4 243 %mul.512 = or i32 %5, %mul.411 244 %arrayidx.6 = getelementptr inbounds i32, i32* %p, i64 6 245 %6 = load i32, i32* %arrayidx.6, align 4 246 %mul.613 = or i32 %6, %mul.512 247 %arrayidx.7 = getelementptr inbounds i32, i32* %p, i64 7 248 %7 = load i32, i32* %arrayidx.7, align 4 249 %mul.714 = or i32 %7, %mul.613 250 ret i32 %mul.714 251} 252 253; int test_xor(unsigned int *p) { 254; int result = 0; 255; for (int i = 0; i < 8; i++) 256; result ^= p[i]; 257; return result; 258; } 259 260define i32 @test_xor(i32* nocapture readonly %p) { 261; CHECK-LABEL: @test_xor( 262; CHECK-NEXT: entry: 263; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1 264; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 2 265; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 3 266; CHECK-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 267; CHECK-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 5 268; CHECK-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 6 269; CHECK-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7 270; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[P]] to <8 x i32>* 271; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, <8 x i32>* [[TMP0]], align 4 272; CHECK-NEXT: [[MUL_18:%.*]] = xor i32 undef, undef 273; CHECK-NEXT: [[MUL_29:%.*]] = xor i32 undef, [[MUL_18]] 274; CHECK-NEXT: [[MUL_310:%.*]] = xor i32 undef, [[MUL_29]] 275; CHECK-NEXT: [[MUL_411:%.*]] = xor i32 undef, [[MUL_310]] 276; CHECK-NEXT: [[MUL_512:%.*]] = xor i32 undef, [[MUL_411]] 277; CHECK-NEXT: [[MUL_613:%.*]] = xor i32 undef, [[MUL_512]] 278; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef> 279; CHECK-NEXT: [[BIN_RDX:%.*]] = xor <8 x i32> [[TMP1]], [[RDX_SHUF]] 280; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <8 x i32> [[BIN_RDX]], <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 281; CHECK-NEXT: [[BIN_RDX2:%.*]] = xor <8 x i32> [[BIN_RDX]], [[RDX_SHUF1]] 282; CHECK-NEXT: [[RDX_SHUF3:%.*]] = shufflevector <8 x i32> [[BIN_RDX2]], <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> 283; CHECK-NEXT: [[BIN_RDX4:%.*]] = xor <8 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] 284; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i32> [[BIN_RDX4]], i32 0 285; CHECK-NEXT: [[MUL_714:%.*]] = xor i32 undef, [[MUL_613]] 286; CHECK-NEXT: ret i32 [[TMP2]] 287; 288entry: 289 %0 = load i32, i32* %p, align 4 290 %arrayidx.1 = getelementptr inbounds i32, i32* %p, i64 1 291 %1 = load i32, i32* %arrayidx.1, align 4 292 %mul.18 = xor i32 %1, %0 293 %arrayidx.2 = getelementptr inbounds i32, i32* %p, i64 2 294 %2 = load i32, i32* %arrayidx.2, align 4 295 %mul.29 = xor i32 %2, %mul.18 296 %arrayidx.3 = getelementptr inbounds i32, i32* %p, i64 3 297 %3 = load i32, i32* %arrayidx.3, align 4 298 %mul.310 = xor i32 %3, %mul.29 299 %arrayidx.4 = getelementptr inbounds i32, i32* %p, i64 4 300 %4 = load i32, i32* %arrayidx.4, align 4 301 %mul.411 = xor i32 %4, %mul.310 302 %arrayidx.5 = getelementptr inbounds i32, i32* %p, i64 5 303 %5 = load i32, i32* %arrayidx.5, align 4 304 %mul.512 = xor i32 %5, %mul.411 305 %arrayidx.6 = getelementptr inbounds i32, i32* %p, i64 6 306 %6 = load i32, i32* %arrayidx.6, align 4 307 %mul.613 = xor i32 %6, %mul.512 308 %arrayidx.7 = getelementptr inbounds i32, i32* %p, i64 7 309 %7 = load i32, i32* %arrayidx.7, align 4 310 %mul.714 = xor i32 %7, %mul.613 311 ret i32 %mul.714 312} 313 314define i32 @PR37731(<4 x i32>* noalias nocapture dereferenceable(16) %self) unnamed_addr #0 { 315; CHECK-LABEL: @PR37731( 316; CHECK-NEXT: entry: 317; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, <4 x i32>* [[SELF:%.*]], align 16 318; CHECK-NEXT: [[TMP1:%.*]] = shl <4 x i32> [[TMP0]], <i32 6, i32 2, i32 13, i32 3> 319; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], [[TMP0]] 320; CHECK-NEXT: [[TMP3:%.*]] = lshr <4 x i32> [[TMP2]], <i32 13, i32 27, i32 21, i32 12> 321; CHECK-NEXT: [[TMP4:%.*]] = and <4 x i32> [[TMP0]], <i32 -2, i32 -8, i32 -16, i32 -128> 322; CHECK-NEXT: [[TMP5:%.*]] = shl <4 x i32> [[TMP4]], <i32 18, i32 2, i32 7, i32 13> 323; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i32> [[TMP3]], [[TMP5]] 324; CHECK-NEXT: store <4 x i32> [[TMP6]], <4 x i32>* [[SELF]], align 16 325; CHECK-NEXT: [[TMP7:%.*]] = xor i32 undef, undef 326; CHECK-NEXT: [[TMP8:%.*]] = xor i32 [[TMP7]], undef 327; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[TMP6]], <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> 328; CHECK-NEXT: [[BIN_RDX:%.*]] = xor <4 x i32> [[TMP6]], [[RDX_SHUF]] 329; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <4 x i32> [[BIN_RDX]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 330; CHECK-NEXT: [[BIN_RDX2:%.*]] = xor <4 x i32> [[BIN_RDX]], [[RDX_SHUF1]] 331; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i32> [[BIN_RDX2]], i32 0 332; CHECK-NEXT: [[TMP10:%.*]] = xor i32 [[TMP8]], undef 333; CHECK-NEXT: ret i32 [[TMP9]] 334; 335entry: 336 %0 = load <4 x i32>, <4 x i32>* %self, align 16 337 %1 = shl <4 x i32> %0, <i32 6, i32 2, i32 13, i32 3> 338 %2 = xor <4 x i32> %1, %0 339 %3 = lshr <4 x i32> %2, <i32 13, i32 27, i32 21, i32 12> 340 %4 = and <4 x i32> %0, <i32 -2, i32 -8, i32 -16, i32 -128> 341 %5 = shl <4 x i32> %4, <i32 18, i32 2, i32 7, i32 13> 342 %6 = xor <4 x i32> %3, %5 343 store <4 x i32> %6, <4 x i32>* %self, align 16 344 %7 = extractelement <4 x i32> %6, i32 0 345 %8 = extractelement <4 x i32> %6, i32 1 346 %9 = xor i32 %7, %8 347 %10 = extractelement <4 x i32> %6, i32 2 348 %11 = xor i32 %9, %10 349 %12 = extractelement <4 x i32> %6, i32 3 350 %13 = xor i32 %11, %12 351 ret i32 %13 352} 353