1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s 3 4%v8i8 = type { i8, i8, i8, i8, i8, i8, i8, i8 } 5 6; https://bugs.llvm.org/show_bug.cgi?id=43146 7 8define i64 @load_bswap(ptr %p) { 9; CHECK-LABEL: @load_bswap( 10; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1 11; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2 12; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3 13; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4 14; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5 15; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6 16; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7 17; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1 18; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1 19; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1 20; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1 21; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1 22; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1 23; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1 24; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1 25; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64 26; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64 27; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64 28; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64 29; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64 30; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64 31; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64 32; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64 33; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56 34; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48 35; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40 36; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32 37; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24 38; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16 39; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8 40; CHECK-NEXT: [[OR01:%.*]] = or i64 [[SH0]], [[SH1]] 41; CHECK-NEXT: [[OR012:%.*]] = or i64 [[OR01]], [[SH2]] 42; CHECK-NEXT: [[OR0123:%.*]] = or i64 [[OR012]], [[SH3]] 43; CHECK-NEXT: [[OR01234:%.*]] = or i64 [[OR0123]], [[SH4]] 44; CHECK-NEXT: [[OR012345:%.*]] = or i64 [[OR01234]], [[SH5]] 45; CHECK-NEXT: [[OR0123456:%.*]] = or i64 [[OR012345]], [[SH6]] 46; CHECK-NEXT: [[OR01234567:%.*]] = or i64 [[OR0123456]], [[Z7]] 47; CHECK-NEXT: ret i64 [[OR01234567]] 48; 49 %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1 50 %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2 51 %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3 52 %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4 53 %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5 54 %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6 55 %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7 56 57 %t0 = load i8, ptr %p 58 %t1 = load i8, ptr %g1 59 %t2 = load i8, ptr %g2 60 %t3 = load i8, ptr %g3 61 %t4 = load i8, ptr %g4 62 %t5 = load i8, ptr %g5 63 %t6 = load i8, ptr %g6 64 %t7 = load i8, ptr %g7 65 66 %z0 = zext i8 %t0 to i64 67 %z1 = zext i8 %t1 to i64 68 %z2 = zext i8 %t2 to i64 69 %z3 = zext i8 %t3 to i64 70 %z4 = zext i8 %t4 to i64 71 %z5 = zext i8 %t5 to i64 72 %z6 = zext i8 %t6 to i64 73 %z7 = zext i8 %t7 to i64 74 75 %sh0 = shl nuw i64 %z0, 56 76 %sh1 = shl nuw nsw i64 %z1, 48 77 %sh2 = shl nuw nsw i64 %z2, 40 78 %sh3 = shl nuw nsw i64 %z3, 32 79 %sh4 = shl nuw nsw i64 %z4, 24 80 %sh5 = shl nuw nsw i64 %z5, 16 81 %sh6 = shl nuw nsw i64 %z6, 8 82; %sh7 = shl nuw nsw i64 %z7, 0 <-- missing phantom shift 83 84 %or01 = or i64 %sh0, %sh1 85 %or012 = or i64 %or01, %sh2 86 %or0123 = or i64 %or012, %sh3 87 %or01234 = or i64 %or0123, %sh4 88 %or012345 = or i64 %or01234, %sh5 89 %or0123456 = or i64 %or012345, %sh6 90 %or01234567 = or i64 %or0123456, %z7 91 ret i64 %or01234567 92} 93 94define i64 @load_bswap_nop_shift(ptr %p) { 95; CHECK-LABEL: @load_bswap_nop_shift( 96; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1 97; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2 98; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3 99; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4 100; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5 101; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6 102; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7 103; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1 104; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1 105; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1 106; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1 107; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1 108; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1 109; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1 110; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1 111; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64 112; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64 113; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64 114; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64 115; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64 116; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64 117; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64 118; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64 119; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56 120; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48 121; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40 122; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32 123; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24 124; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16 125; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8 126; CHECK-NEXT: [[SH7:%.*]] = shl nuw nsw i64 [[Z7]], 0 127; CHECK-NEXT: [[OR01:%.*]] = or i64 [[SH0]], [[SH1]] 128; CHECK-NEXT: [[OR012:%.*]] = or i64 [[OR01]], [[SH2]] 129; CHECK-NEXT: [[OR0123:%.*]] = or i64 [[OR012]], [[SH3]] 130; CHECK-NEXT: [[OR01234:%.*]] = or i64 [[OR0123]], [[SH4]] 131; CHECK-NEXT: [[OR012345:%.*]] = or i64 [[OR01234]], [[SH5]] 132; CHECK-NEXT: [[OR0123456:%.*]] = or i64 [[OR012345]], [[SH6]] 133; CHECK-NEXT: [[OR01234567:%.*]] = or i64 [[OR0123456]], [[SH7]] 134; CHECK-NEXT: ret i64 [[OR01234567]] 135; 136 %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1 137 %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2 138 %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3 139 %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4 140 %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5 141 %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6 142 %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7 143 144 %t0 = load i8, ptr %p 145 %t1 = load i8, ptr %g1 146 %t2 = load i8, ptr %g2 147 %t3 = load i8, ptr %g3 148 %t4 = load i8, ptr %g4 149 %t5 = load i8, ptr %g5 150 %t6 = load i8, ptr %g6 151 %t7 = load i8, ptr %g7 152 153 %z0 = zext i8 %t0 to i64 154 %z1 = zext i8 %t1 to i64 155 %z2 = zext i8 %t2 to i64 156 %z3 = zext i8 %t3 to i64 157 %z4 = zext i8 %t4 to i64 158 %z5 = zext i8 %t5 to i64 159 %z6 = zext i8 %t6 to i64 160 %z7 = zext i8 %t7 to i64 161 162 %sh0 = shl nuw i64 %z0, 56 163 %sh1 = shl nuw nsw i64 %z1, 48 164 %sh2 = shl nuw nsw i64 %z2, 40 165 %sh3 = shl nuw nsw i64 %z3, 32 166 %sh4 = shl nuw nsw i64 %z4, 24 167 %sh5 = shl nuw nsw i64 %z5, 16 168 %sh6 = shl nuw nsw i64 %z6, 8 169 %sh7 = shl nuw nsw i64 %z7, 0 170 171 %or01 = or i64 %sh0, %sh1 172 %or012 = or i64 %or01, %sh2 173 %or0123 = or i64 %or012, %sh3 174 %or01234 = or i64 %or0123, %sh4 175 %or012345 = or i64 %or01234, %sh5 176 %or0123456 = or i64 %or012345, %sh6 177 %or01234567 = or i64 %or0123456, %sh7 178 ret i64 %or01234567 179} 180 181; https://bugs.llvm.org/show_bug.cgi?id=42708 182 183define i64 @load64le(ptr %arg) { 184; CHECK-LABEL: @load64le( 185; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1 186; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 187; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3 188; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4 189; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5 190; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6 191; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7 192; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1 193; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1 194; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1 195; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1 196; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1 197; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1 198; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1 199; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1 200; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64 201; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64 202; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64 203; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64 204; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64 205; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64 206; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64 207; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64 208; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8 209; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16 210; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24 211; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32 212; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40 213; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48 214; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56 215; CHECK-NEXT: [[O1:%.*]] = or i64 [[S1]], [[Z0]] 216; CHECK-NEXT: [[O2:%.*]] = or i64 [[O1]], [[S2]] 217; CHECK-NEXT: [[O3:%.*]] = or i64 [[O2]], [[S3]] 218; CHECK-NEXT: [[O4:%.*]] = or i64 [[O3]], [[S4]] 219; CHECK-NEXT: [[O5:%.*]] = or i64 [[O4]], [[S5]] 220; CHECK-NEXT: [[O6:%.*]] = or i64 [[O5]], [[S6]] 221; CHECK-NEXT: [[O7:%.*]] = or i64 [[O6]], [[S7]] 222; CHECK-NEXT: ret i64 [[O7]] 223; 224 %g1 = getelementptr inbounds i8, ptr %arg, i64 1 225 %g2 = getelementptr inbounds i8, ptr %arg, i64 2 226 %g3 = getelementptr inbounds i8, ptr %arg, i64 3 227 %g4 = getelementptr inbounds i8, ptr %arg, i64 4 228 %g5 = getelementptr inbounds i8, ptr %arg, i64 5 229 %g6 = getelementptr inbounds i8, ptr %arg, i64 6 230 %g7 = getelementptr inbounds i8, ptr %arg, i64 7 231 232 %ld0 = load i8, ptr %arg, align 1 233 %ld1 = load i8, ptr %g1, align 1 234 %ld2 = load i8, ptr %g2, align 1 235 %ld3 = load i8, ptr %g3, align 1 236 %ld4 = load i8, ptr %g4, align 1 237 %ld5 = load i8, ptr %g5, align 1 238 %ld6 = load i8, ptr %g6, align 1 239 %ld7 = load i8, ptr %g7, align 1 240 241 %z0 = zext i8 %ld0 to i64 242 %z1 = zext i8 %ld1 to i64 243 %z2 = zext i8 %ld2 to i64 244 %z3 = zext i8 %ld3 to i64 245 %z4 = zext i8 %ld4 to i64 246 %z5 = zext i8 %ld5 to i64 247 %z6 = zext i8 %ld6 to i64 248 %z7 = zext i8 %ld7 to i64 249 250; %s0 = shl nuw nsw i64 %z0, 0 <-- missing phantom shift 251 %s1 = shl nuw nsw i64 %z1, 8 252 %s2 = shl nuw nsw i64 %z2, 16 253 %s3 = shl nuw nsw i64 %z3, 24 254 %s4 = shl nuw nsw i64 %z4, 32 255 %s5 = shl nuw nsw i64 %z5, 40 256 %s6 = shl nuw nsw i64 %z6, 48 257 %s7 = shl nuw i64 %z7, 56 258 259 %o1 = or i64 %s1, %z0 260 %o2 = or i64 %o1, %s2 261 %o3 = or i64 %o2, %s3 262 %o4 = or i64 %o3, %s4 263 %o5 = or i64 %o4, %s5 264 %o6 = or i64 %o5, %s6 265 %o7 = or i64 %o6, %s7 266 ret i64 %o7 267} 268 269define i64 @load64le_nop_shift(ptr %arg) { 270; CHECK-LABEL: @load64le_nop_shift( 271; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1 272; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 273; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3 274; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4 275; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5 276; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6 277; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7 278; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1 279; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1 280; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1 281; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1 282; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1 283; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1 284; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1 285; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1 286; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64 287; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64 288; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64 289; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64 290; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64 291; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64 292; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64 293; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64 294; CHECK-NEXT: [[S0:%.*]] = shl nuw nsw i64 [[Z0]], 0 295; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8 296; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16 297; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24 298; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32 299; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40 300; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48 301; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56 302; CHECK-NEXT: [[O1:%.*]] = or i64 [[S1]], [[S0]] 303; CHECK-NEXT: [[O2:%.*]] = or i64 [[O1]], [[S2]] 304; CHECK-NEXT: [[O3:%.*]] = or i64 [[O2]], [[S3]] 305; CHECK-NEXT: [[O4:%.*]] = or i64 [[O3]], [[S4]] 306; CHECK-NEXT: [[O5:%.*]] = or i64 [[O4]], [[S5]] 307; CHECK-NEXT: [[O6:%.*]] = or i64 [[O5]], [[S6]] 308; CHECK-NEXT: [[O7:%.*]] = or i64 [[O6]], [[S7]] 309; CHECK-NEXT: ret i64 [[O7]] 310; 311 %g1 = getelementptr inbounds i8, ptr %arg, i64 1 312 %g2 = getelementptr inbounds i8, ptr %arg, i64 2 313 %g3 = getelementptr inbounds i8, ptr %arg, i64 3 314 %g4 = getelementptr inbounds i8, ptr %arg, i64 4 315 %g5 = getelementptr inbounds i8, ptr %arg, i64 5 316 %g6 = getelementptr inbounds i8, ptr %arg, i64 6 317 %g7 = getelementptr inbounds i8, ptr %arg, i64 7 318 319 %ld0 = load i8, ptr %arg, align 1 320 %ld1 = load i8, ptr %g1, align 1 321 %ld2 = load i8, ptr %g2, align 1 322 %ld3 = load i8, ptr %g3, align 1 323 %ld4 = load i8, ptr %g4, align 1 324 %ld5 = load i8, ptr %g5, align 1 325 %ld6 = load i8, ptr %g6, align 1 326 %ld7 = load i8, ptr %g7, align 1 327 328 %z0 = zext i8 %ld0 to i64 329 %z1 = zext i8 %ld1 to i64 330 %z2 = zext i8 %ld2 to i64 331 %z3 = zext i8 %ld3 to i64 332 %z4 = zext i8 %ld4 to i64 333 %z5 = zext i8 %ld5 to i64 334 %z6 = zext i8 %ld6 to i64 335 %z7 = zext i8 %ld7 to i64 336 337 %s0 = shl nuw nsw i64 %z0, 0 338 %s1 = shl nuw nsw i64 %z1, 8 339 %s2 = shl nuw nsw i64 %z2, 16 340 %s3 = shl nuw nsw i64 %z3, 24 341 %s4 = shl nuw nsw i64 %z4, 32 342 %s5 = shl nuw nsw i64 %z5, 40 343 %s6 = shl nuw nsw i64 %z6, 48 344 %s7 = shl nuw i64 %z7, 56 345 346 %o1 = or i64 %s1, %s0 347 %o2 = or i64 %o1, %s2 348 %o3 = or i64 %o2, %s3 349 %o4 = or i64 %o3, %s4 350 %o5 = or i64 %o4, %s5 351 %o6 = or i64 %o5, %s6 352 %o7 = or i64 %o6, %s7 353 ret i64 %o7 354} 355 356define void @PR39538(ptr %t0, ptr %t1) { 357; CHECK-LABEL: @PR39538( 358; CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds i8, ptr [[T0:%.*]], i64 1 359; CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 2 360; CHECK-NEXT: [[T16:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 3 361; CHECK-NEXT: [[T20:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 4 362; CHECK-NEXT: [[T24:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 5 363; CHECK-NEXT: [[T29:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 6 364; CHECK-NEXT: [[T34:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 7 365; CHECK-NEXT: [[T39:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 8 366; CHECK-NEXT: [[T43:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 9 367; CHECK-NEXT: [[T48:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 10 368; CHECK-NEXT: [[T53:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 11 369; CHECK-NEXT: [[T58:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 12 370; CHECK-NEXT: [[T62:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 13 371; CHECK-NEXT: [[T67:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 14 372; CHECK-NEXT: [[T72:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 15 373; CHECK-NEXT: [[T38:%.*]] = getelementptr inbounds i32, ptr [[T1:%.*]], i64 1 374; CHECK-NEXT: [[T57:%.*]] = getelementptr inbounds i32, ptr [[T1]], i64 2 375; CHECK-NEXT: [[T76:%.*]] = getelementptr inbounds i32, ptr [[T1]], i64 3 376; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[T0]], align 1 377; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[T6]], align 1 378; CHECK-NEXT: [[T12:%.*]] = load i8, ptr [[T11]], align 1 379; CHECK-NEXT: [[T17:%.*]] = load i8, ptr [[T16]], align 1 380; CHECK-NEXT: [[T21:%.*]] = load i8, ptr [[T20]], align 1 381; CHECK-NEXT: [[T25:%.*]] = load i8, ptr [[T24]], align 1 382; CHECK-NEXT: [[T30:%.*]] = load i8, ptr [[T29]], align 1 383; CHECK-NEXT: [[T35:%.*]] = load i8, ptr [[T34]], align 1 384; CHECK-NEXT: [[T40:%.*]] = load i8, ptr [[T39]], align 1 385; CHECK-NEXT: [[T44:%.*]] = load i8, ptr [[T43]], align 1 386; CHECK-NEXT: [[T49:%.*]] = load i8, ptr [[T48]], align 1 387; CHECK-NEXT: [[T54:%.*]] = load i8, ptr [[T53]], align 1 388; CHECK-NEXT: [[T59:%.*]] = load i8, ptr [[T58]], align 1 389; CHECK-NEXT: [[T63:%.*]] = load i8, ptr [[T62]], align 1 390; CHECK-NEXT: [[T68:%.*]] = load i8, ptr [[T67]], align 1 391; CHECK-NEXT: [[T73:%.*]] = load i8, ptr [[T72]], align 1 392; CHECK-NEXT: [[T4:%.*]] = zext i8 [[T3]] to i32 393; CHECK-NEXT: [[T8:%.*]] = zext i8 [[T7]] to i32 394; CHECK-NEXT: [[T13:%.*]] = zext i8 [[T12]] to i32 395; CHECK-NEXT: [[T18:%.*]] = zext i8 [[T17]] to i32 396; CHECK-NEXT: [[T22:%.*]] = zext i8 [[T21]] to i32 397; CHECK-NEXT: [[T26:%.*]] = zext i8 [[T25]] to i32 398; CHECK-NEXT: [[T31:%.*]] = zext i8 [[T30]] to i32 399; CHECK-NEXT: [[T36:%.*]] = zext i8 [[T35]] to i32 400; CHECK-NEXT: [[T41:%.*]] = zext i8 [[T40]] to i32 401; CHECK-NEXT: [[T45:%.*]] = zext i8 [[T44]] to i32 402; CHECK-NEXT: [[T50:%.*]] = zext i8 [[T49]] to i32 403; CHECK-NEXT: [[T55:%.*]] = zext i8 [[T54]] to i32 404; CHECK-NEXT: [[T60:%.*]] = zext i8 [[T59]] to i32 405; CHECK-NEXT: [[T64:%.*]] = zext i8 [[T63]] to i32 406; CHECK-NEXT: [[T69:%.*]] = zext i8 [[T68]] to i32 407; CHECK-NEXT: [[T74:%.*]] = zext i8 [[T73]] to i32 408; CHECK-NEXT: [[T5:%.*]] = shl nuw i32 [[T4]], 24 409; CHECK-NEXT: [[T23:%.*]] = shl nuw i32 [[T22]], 24 410; CHECK-NEXT: [[T42:%.*]] = shl nuw i32 [[T41]], 24 411; CHECK-NEXT: [[T61:%.*]] = shl nuw i32 [[T60]], 24 412; CHECK-NEXT: [[T9:%.*]] = shl nuw nsw i32 [[T8]], 16 413; CHECK-NEXT: [[T27:%.*]] = shl nuw nsw i32 [[T26]], 16 414; CHECK-NEXT: [[T46:%.*]] = shl nuw nsw i32 [[T45]], 16 415; CHECK-NEXT: [[T65:%.*]] = shl nuw nsw i32 [[T64]], 16 416; CHECK-NEXT: [[T14:%.*]] = shl nuw nsw i32 [[T13]], 8 417; CHECK-NEXT: [[T32:%.*]] = shl nuw nsw i32 [[T31]], 8 418; CHECK-NEXT: [[T51:%.*]] = shl nuw nsw i32 [[T50]], 8 419; CHECK-NEXT: [[T70:%.*]] = shl nuw nsw i32 [[T69]], 8 420; CHECK-NEXT: [[T10:%.*]] = or i32 [[T9]], [[T5]] 421; CHECK-NEXT: [[T15:%.*]] = or i32 [[T10]], [[T14]] 422; CHECK-NEXT: [[T19:%.*]] = or i32 [[T15]], [[T18]] 423; CHECK-NEXT: [[T28:%.*]] = or i32 [[T27]], [[T23]] 424; CHECK-NEXT: [[T33:%.*]] = or i32 [[T28]], [[T32]] 425; CHECK-NEXT: [[T37:%.*]] = or i32 [[T33]], [[T36]] 426; CHECK-NEXT: [[T47:%.*]] = or i32 [[T46]], [[T42]] 427; CHECK-NEXT: [[T52:%.*]] = or i32 [[T47]], [[T51]] 428; CHECK-NEXT: [[T56:%.*]] = or i32 [[T52]], [[T55]] 429; CHECK-NEXT: [[T66:%.*]] = or i32 [[T65]], [[T61]] 430; CHECK-NEXT: [[T71:%.*]] = or i32 [[T66]], [[T70]] 431; CHECK-NEXT: [[T75:%.*]] = or i32 [[T71]], [[T74]] 432; CHECK-NEXT: store i32 [[T19]], ptr [[T1]], align 4 433; CHECK-NEXT: store i32 [[T37]], ptr [[T38]], align 4 434; CHECK-NEXT: store i32 [[T56]], ptr [[T57]], align 4 435; CHECK-NEXT: store i32 [[T75]], ptr [[T76]], align 4 436; CHECK-NEXT: ret void 437; 438 %t6 = getelementptr inbounds i8, ptr %t0, i64 1 439 %t11 = getelementptr inbounds i8, ptr %t0, i64 2 440 %t16 = getelementptr inbounds i8, ptr %t0, i64 3 441 %t20 = getelementptr inbounds i8, ptr %t0, i64 4 442 %t24 = getelementptr inbounds i8, ptr %t0, i64 5 443 %t29 = getelementptr inbounds i8, ptr %t0, i64 6 444 %t34 = getelementptr inbounds i8, ptr %t0, i64 7 445 %t39 = getelementptr inbounds i8, ptr %t0, i64 8 446 %t43 = getelementptr inbounds i8, ptr %t0, i64 9 447 %t48 = getelementptr inbounds i8, ptr %t0, i64 10 448 %t53 = getelementptr inbounds i8, ptr %t0, i64 11 449 %t58 = getelementptr inbounds i8, ptr %t0, i64 12 450 %t62 = getelementptr inbounds i8, ptr %t0, i64 13 451 %t67 = getelementptr inbounds i8, ptr %t0, i64 14 452 %t72 = getelementptr inbounds i8, ptr %t0, i64 15 453 %t38 = getelementptr inbounds i32, ptr %t1, i64 1 454 %t57 = getelementptr inbounds i32, ptr %t1, i64 2 455 %t76 = getelementptr inbounds i32, ptr %t1, i64 3 456 %t3 = load i8, ptr %t0, align 1 457 %t7 = load i8, ptr %t6, align 1 458 %t12 = load i8, ptr %t11, align 1 459 %t17 = load i8, ptr %t16, align 1 460 %t21 = load i8, ptr %t20, align 1 461 %t25 = load i8, ptr %t24, align 1 462 %t30 = load i8, ptr %t29, align 1 463 %t35 = load i8, ptr %t34, align 1 464 %t40 = load i8, ptr %t39, align 1 465 %t44 = load i8, ptr %t43, align 1 466 %t49 = load i8, ptr %t48, align 1 467 %t54 = load i8, ptr %t53, align 1 468 %t59 = load i8, ptr %t58, align 1 469 %t63 = load i8, ptr %t62, align 1 470 %t68 = load i8, ptr %t67, align 1 471 %t73 = load i8, ptr %t72, align 1 472 %t4 = zext i8 %t3 to i32 473 %t8 = zext i8 %t7 to i32 474 %t13 = zext i8 %t12 to i32 475 %t18 = zext i8 %t17 to i32 476 %t22 = zext i8 %t21 to i32 477 %t26 = zext i8 %t25 to i32 478 %t31 = zext i8 %t30 to i32 479 %t36 = zext i8 %t35 to i32 480 %t41 = zext i8 %t40 to i32 481 %t45 = zext i8 %t44 to i32 482 %t50 = zext i8 %t49 to i32 483 %t55 = zext i8 %t54 to i32 484 %t60 = zext i8 %t59 to i32 485 %t64 = zext i8 %t63 to i32 486 %t69 = zext i8 %t68 to i32 487 %t74 = zext i8 %t73 to i32 488 %t5 = shl nuw i32 %t4, 24 489 %t23 = shl nuw i32 %t22, 24 490 %t42 = shl nuw i32 %t41, 24 491 %t61 = shl nuw i32 %t60, 24 492 %t9 = shl nuw nsw i32 %t8, 16 493 %t27 = shl nuw nsw i32 %t26, 16 494 %t46 = shl nuw nsw i32 %t45, 16 495 %t65 = shl nuw nsw i32 %t64, 16 496 %t14 = shl nuw nsw i32 %t13, 8 497 %t32 = shl nuw nsw i32 %t31, 8 498 %t51 = shl nuw nsw i32 %t50, 8 499 %t70 = shl nuw nsw i32 %t69, 8 500 %t10 = or i32 %t9, %t5 501 %t15 = or i32 %t10, %t14 502 %t19 = or i32 %t15, %t18 503 %t28 = or i32 %t27, %t23 504 %t33 = or i32 %t28, %t32 505 %t37 = or i32 %t33, %t36 506 %t47 = or i32 %t46, %t42 507 %t52 = or i32 %t47, %t51 508 %t56 = or i32 %t52, %t55 509 %t66 = or i32 %t65, %t61 510 %t71 = or i32 %t66, %t70 511 %t75 = or i32 %t71, %t74 512 store i32 %t19, ptr %t1, align 4 513 store i32 %t37, ptr %t38, align 4 514 store i32 %t56, ptr %t57, align 4 515 store i32 %t75, ptr %t76, align 4 516 ret void 517} 518 519; Do not crash on constant expressions. 520 521@g1 = external dso_local unnamed_addr constant [8 x i8], align 1 522@g2 = external dso_local unnamed_addr constant [5 x i8], align 1 523 524define void @load_combine_constant_expression(ptr %t1) { 525; CHECK-LABEL: @load_combine_constant_expression( 526; CHECK-NEXT: [[EXT1:%.*]] = zext i32 ptrtoint (ptr @g1 to i32) to i64 527; CHECK-NEXT: [[EXT2:%.*]] = zext i32 ptrtoint (ptr @g2 to i32) to i64 528; CHECK-NEXT: [[SHL1:%.*]] = shl i64 [[EXT1]], 32 529; CHECK-NEXT: [[OR1:%.*]] = or i64 [[SHL1]], [[EXT2]] 530; CHECK-NEXT: store i64 [[OR1]], ptr [[T1:%.*]], align 4 531; CHECK-NEXT: [[T3:%.*]] = getelementptr i64, ptr [[T1]], i64 1 532; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[EXT1]], 32 533; CHECK-NEXT: [[OR2:%.*]] = or i64 [[SHL2]], [[EXT2]] 534; CHECK-NEXT: store i64 [[OR2]], ptr [[T3]], align 4 535; CHECK-NEXT: ret void 536; 537 %ext1 = zext i32 ptrtoint (ptr @g1 to i32) to i64 538 %ext2 = zext i32 ptrtoint (ptr @g2 to i32) to i64 539 %shl1 = shl i64 %ext1, 32 540 %or1 = or i64 %shl1, %ext2 541 store i64 %or1, ptr %t1, align 4 542 %t3 = getelementptr i64, ptr %t1, i64 1 543 %shl2 = shl i64 %ext1, 32 544 %or2 = or i64 %shl2, %ext2 545 store i64 %or2, ptr %t3, align 4 546 ret void 547} 548 549@output = dso_local local_unnamed_addr global [8 x i32] zeroinitializer, align 16 550 551define void @PR47450(ptr nocapture readonly %p) { 552; CHECK-LABEL: @PR47450( 553; CHECK-NEXT: [[X:%.*]] = load i16, ptr [[P:%.*]], align 2 554; CHECK-NEXT: [[Z:%.*]] = zext i16 [[X]] to i32 555; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 1 556; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[S]], i32 0 557; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer 558; CHECK-NEXT: store <4 x i32> [[TMP2]], ptr @output, align 16 559; CHECK-NEXT: ret void 560; 561 %x = load i16, ptr %p, align 2 562 %z = zext i16 %x to i32 563 %s = shl nuw nsw i32 %z, 1 564 store i32 %s, ptr @output, align 16 565 store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 1), align 4 566 store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 2), align 8 567 store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 3), align 4 568 ret void 569} 570