1; RUN: llc -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s 2; RUN: llc -O3 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=O3 3 4; This file checks that the translation from llvm IR to generic MachineInstr 5; is correct. 6target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 7target triple = "aarch64--" 8 9; Tests for add. 10; CHECK-LABEL: name: addi64 11; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 12; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1 13; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_ADD [[ARG1]], [[ARG2]] 14; CHECK-NEXT: $x0 = COPY [[RES]] 15; CHECK-NEXT: RET_ReallyLR implicit $x0 16define i64 @addi64(i64 %arg1, i64 %arg2) { 17 %res = add i64 %arg1, %arg2 18 ret i64 %res 19} 20 21; CHECK-LABEL: name: muli64 22; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 23; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1 24; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_MUL [[ARG1]], [[ARG2]] 25; CHECK-NEXT: $x0 = COPY [[RES]] 26; CHECK-NEXT: RET_ReallyLR implicit $x0 27define i64 @muli64(i64 %arg1, i64 %arg2) { 28 %res = mul i64 %arg1, %arg2 29 ret i64 %res 30} 31 32; Tests for alloca 33; CHECK-LABEL: name: allocai64 34; CHECK: stack: 35; CHECK-NEXT: - { id: 0, name: ptr1, type: default, offset: 0, size: 8, alignment: 8, 36; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true, 37; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } 38; CHECK-NEXT: - { id: 1, name: ptr2, type: default, offset: 0, size: 8, alignment: 1, 39; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true, 40; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } 41; CHECK-NEXT: - { id: 2, name: ptr3, type: default, offset: 0, size: 128, alignment: 8, 42; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true, 43; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } 44; CHECK-NEXT: - { id: 3, name: ptr4, type: default, offset: 0, size: 1, alignment: 8, 45; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.ptr1 46; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.1.ptr2 47; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.2.ptr3 48; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.3.ptr4 49define void @allocai64() { 50 %ptr1 = alloca i64 51 %ptr2 = alloca i64, align 1 52 %ptr3 = alloca i64, i32 16 53 %ptr4 = alloca [0 x i64] 54 ret void 55} 56 57; Tests for br. 58; CHECK-LABEL: name: uncondbr 59; CHECK: body: 60; 61; ABI/constant lowering and IR-level entry basic block. 62; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}: 63; 64; Make sure we have one successor and only one. 65; CHECK-NEXT: successors: %[[BB2:bb.[0-9]+]](0x80000000) 66; 67; Check that we emit the correct branch. 68; CHECK: G_BR %[[BB2]] 69; 70; Check that end contains the return instruction. 71; CHECK: [[END:bb.[0-9]+]].{{[a-zA-Z0-9.]+}}: 72; CHECK-NEXT: RET_ReallyLR 73; 74; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}: 75; CHECK-NEXT: successors: %[[END]](0x80000000) 76; CHECK: G_BR %[[END]] 77define void @uncondbr() { 78entry: 79 br label %bb2 80end: 81 ret void 82bb2: 83 br label %end 84} 85 86; CHECK-LABEL: name: uncondbr_fallthrough 87; CHECK: body: 88; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}: 89; CHECK-NEXT: successors: %[[END:bb.[0-9]+]](0x80000000) 90; We don't emit a branch here, as we can fallthrough to the successor. 91; CHECK-NOT: G_BR 92; CHECK: [[END]].{{[a-zA-Z0-9.]+}}: 93; CHECK-NEXT: RET_ReallyLR 94define void @uncondbr_fallthrough() { 95entry: 96 br label %end 97end: 98 ret void 99} 100 101; Tests for conditional br. 102; CHECK-LABEL: name: condbr 103; CHECK: body: 104; 105; ABI/constant lowering and IR-level entry basic block. 106; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}): 107; Make sure we have two successors 108; CHECK-NEXT: successors: %[[TRUE:bb.[0-9]+]](0x40000000), 109; CHECK: %[[FALSE:bb.[0-9]+]](0x40000000) 110; 111; CHECK: [[ADDR:%.*]]:_(p0) = COPY $x0 112; 113; Check that we emit the correct branch. 114; CHECK: [[TST:%.*]]:_(s1) = G_LOAD [[ADDR]](p0) 115; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]] 116; CHECK: G_BR %[[FALSE]] 117; 118; Check that each successor contains the return instruction. 119; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}: 120; CHECK-NEXT: RET_ReallyLR 121; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}: 122; CHECK-NEXT: RET_ReallyLR 123define void @condbr(i1* %tstaddr) { 124 %tst = load i1, i1* %tstaddr 125 br i1 %tst, label %true, label %false 126true: 127 ret void 128false: 129 ret void 130} 131 132; Tests for indirect br. 133; CHECK-LABEL: name: indirectbr 134; CHECK: body: 135; 136; ABI/constant lowering and IR-level entry basic block. 137; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}: 138; Make sure we have one successor 139; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000) 140; CHECK-NOT: G_BR 141; 142; Check basic block L1 has 2 successors: BBL1 and BBL2 143; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken): 144; CHECK-NEXT: successors: %[[BB_L1]](0x40000000), 145; CHECK: %[[BB_L2:bb.[0-9]+]](0x40000000) 146; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0) 147; 148; Check basic block L2 is the return basic block 149; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken): 150; CHECK-NEXT: RET_ReallyLR 151 152@indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8 153 154define void @indirectbr() { 155entry: 156 br label %L1 157L1: ; preds = %entry, %L1 158 %i = phi i32 [ 0, %entry ], [ %inc, %L1 ] 159 %inc = add i32 %i, 1 160 %idxprom = zext i32 %i to i64 161 %arrayidx = getelementptr inbounds [3 x i8*], [3 x i8*]* @indirectbr.L, i64 0, i64 %idxprom 162 %brtarget = load i8*, i8** %arrayidx, align 8 163 indirectbr i8* %brtarget, [label %L1, label %L2] 164L2: ; preds = %L1 165 ret void 166} 167 168; Tests for or. 169; CHECK-LABEL: name: ori64 170; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 171; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1 172; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_OR [[ARG1]], [[ARG2]] 173; CHECK-NEXT: $x0 = COPY [[RES]] 174; CHECK-NEXT: RET_ReallyLR implicit $x0 175define i64 @ori64(i64 %arg1, i64 %arg2) { 176 %res = or i64 %arg1, %arg2 177 ret i64 %res 178} 179 180; CHECK-LABEL: name: ori32 181; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 182; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 183; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_OR [[ARG1]], [[ARG2]] 184; CHECK-NEXT: $w0 = COPY [[RES]] 185; CHECK-NEXT: RET_ReallyLR implicit $w0 186define i32 @ori32(i32 %arg1, i32 %arg2) { 187 %res = or i32 %arg1, %arg2 188 ret i32 %res 189} 190 191; Tests for xor. 192; CHECK-LABEL: name: xori64 193; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 194; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1 195; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_XOR [[ARG1]], [[ARG2]] 196; CHECK-NEXT: $x0 = COPY [[RES]] 197; CHECK-NEXT: RET_ReallyLR implicit $x0 198define i64 @xori64(i64 %arg1, i64 %arg2) { 199 %res = xor i64 %arg1, %arg2 200 ret i64 %res 201} 202 203; CHECK-LABEL: name: xori32 204; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 205; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 206; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_XOR [[ARG1]], [[ARG2]] 207; CHECK-NEXT: $w0 = COPY [[RES]] 208; CHECK-NEXT: RET_ReallyLR implicit $w0 209define i32 @xori32(i32 %arg1, i32 %arg2) { 210 %res = xor i32 %arg1, %arg2 211 ret i32 %res 212} 213 214; Tests for and. 215; CHECK-LABEL: name: andi64 216; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 217; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1 218; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_AND [[ARG1]], [[ARG2]] 219; CHECK-NEXT: $x0 = COPY [[RES]] 220; CHECK-NEXT: RET_ReallyLR implicit $x0 221define i64 @andi64(i64 %arg1, i64 %arg2) { 222 %res = and i64 %arg1, %arg2 223 ret i64 %res 224} 225 226; CHECK-LABEL: name: andi32 227; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 228; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 229; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_AND [[ARG1]], [[ARG2]] 230; CHECK-NEXT: $w0 = COPY [[RES]] 231; CHECK-NEXT: RET_ReallyLR implicit $w0 232define i32 @andi32(i32 %arg1, i32 %arg2) { 233 %res = and i32 %arg1, %arg2 234 ret i32 %res 235} 236 237; Tests for sub. 238; CHECK-LABEL: name: subi64 239; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 240; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1 241; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_SUB [[ARG1]], [[ARG2]] 242; CHECK-NEXT: $x0 = COPY [[RES]] 243; CHECK-NEXT: RET_ReallyLR implicit $x0 244define i64 @subi64(i64 %arg1, i64 %arg2) { 245 %res = sub i64 %arg1, %arg2 246 ret i64 %res 247} 248 249; CHECK-LABEL: name: subi32 250; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 251; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 252; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SUB [[ARG1]], [[ARG2]] 253; CHECK-NEXT: $w0 = COPY [[RES]] 254; CHECK-NEXT: RET_ReallyLR implicit $w0 255define i32 @subi32(i32 %arg1, i32 %arg2) { 256 %res = sub i32 %arg1, %arg2 257 ret i32 %res 258} 259 260; CHECK-LABEL: name: ptrtoint 261; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0 262; CHECK: [[RES:%[0-9]+]]:_(s64) = G_PTRTOINT [[ARG1]] 263; CHECK: $x0 = COPY [[RES]] 264; CHECK: RET_ReallyLR implicit $x0 265define i64 @ptrtoint(i64* %a) { 266 %val = ptrtoint i64* %a to i64 267 ret i64 %val 268} 269 270; CHECK-LABEL: name: inttoptr 271; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 272; CHECK: [[RES:%[0-9]+]]:_(p0) = G_INTTOPTR [[ARG1]] 273; CHECK: $x0 = COPY [[RES]] 274; CHECK: RET_ReallyLR implicit $x0 275define i64* @inttoptr(i64 %a) { 276 %val = inttoptr i64 %a to i64* 277 ret i64* %val 278} 279 280; CHECK-LABEL: name: trivial_bitcast 281; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0 282; CHECK: $x0 = COPY [[ARG1]] 283; CHECK: RET_ReallyLR implicit $x0 284define i64* @trivial_bitcast(i8* %a) { 285 %val = bitcast i8* %a to i64* 286 ret i64* %val 287} 288 289; CHECK-LABEL: name: trivial_bitcast_with_copy 290; CHECK: [[A:%[0-9]+]]:_(p0) = COPY $x0 291; CHECK: G_BR %[[CAST:bb\.[0-9]+]] 292 293; CHECK: [[END:bb\.[0-9]+]].{{[a-zA-Z0-9.]+}}: 294; CHECK: $x0 = COPY [[A]] 295 296; CHECK: [[CAST]].{{[a-zA-Z0-9.]+}}: 297; CHECK: G_BR %[[END]] 298define i64* @trivial_bitcast_with_copy(i8* %a) { 299 br label %cast 300 301end: 302 ret i64* %val 303 304cast: 305 %val = bitcast i8* %a to i64* 306 br label %end 307} 308 309; CHECK-LABEL: name: bitcast 310; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 311; CHECK: [[RES1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[ARG1]] 312; CHECK: [[RES2:%[0-9]+]]:_(s64) = G_BITCAST [[RES1]] 313; CHECK: $x0 = COPY [[RES2]] 314; CHECK: RET_ReallyLR implicit $x0 315define i64 @bitcast(i64 %a) { 316 %res1 = bitcast i64 %a to <2 x i32> 317 %res2 = bitcast <2 x i32> %res1 to i64 318 ret i64 %res2 319} 320 321; CHECK-LABEL: name: addrspacecast 322; CHECK: [[ARG1:%[0-9]+]]:_(p1) = COPY $x0 323; CHECK: [[RES1:%[0-9]+]]:_(p2) = G_ADDRSPACE_CAST [[ARG1]] 324; CHECK: [[RES2:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[RES1]] 325; CHECK: $x0 = COPY [[RES2]] 326; CHECK: RET_ReallyLR implicit $x0 327define i64* @addrspacecast(i32 addrspace(1)* %a) { 328 %res1 = addrspacecast i32 addrspace(1)* %a to i64 addrspace(2)* 329 %res2 = addrspacecast i64 addrspace(2)* %res1 to i64* 330 ret i64* %res2 331} 332 333; CHECK-LABEL: name: trunc 334; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0 335; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_LOAD 336; CHECK: [[RES1:%[0-9]+]]:_(s8) = G_TRUNC [[ARG1]] 337; CHECK: [[RES2:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[VEC]] 338define void @trunc(i64 %a) { 339 %vecptr = alloca <4 x i32> 340 %vec = load <4 x i32>, <4 x i32>* %vecptr 341 %res1 = trunc i64 %a to i8 342 %res2 = trunc <4 x i32> %vec to <4 x i16> 343 ret void 344} 345 346; CHECK-LABEL: name: load 347; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 348; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1 349; CHECK: [[VAL1:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16) 350; CHECK: [[VAL2:%[0-9]+]]:_(s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42, addrspace 42) 351; CHECK: [[SUM2:%.*]]:_(s64) = G_ADD [[VAL1]], [[VAL2]] 352; CHECK: [[VAL3:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (volatile load 8 from %ir.addr) 353; CHECK: [[SUM3:%[0-9]+]]:_(s64) = G_ADD [[SUM2]], [[VAL3]] 354; CHECK: [[VAL4:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, !range !0) 355; CHECK: [[SUM4:%[0-9]+]]:_(s64) = G_ADD [[SUM3]], [[VAL4]] 356; CHECK: $x0 = COPY [[SUM4]] 357; CHECK: RET_ReallyLR implicit $x0 358define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) { 359 %val1 = load i64, i64* %addr, align 16 360 361 %val2 = load i64, i64 addrspace(42)* %addr42 362 %sum2 = add i64 %val1, %val2 363 364 %val3 = load volatile i64, i64* %addr 365 %sum3 = add i64 %sum2, %val3 366 367 %val4 = load i64, i64* %addr, !range !0 368 %sum4 = add i64 %sum3, %val4 369 ret i64 %sum4 370} 371 372; CHECK-LABEL: name: store 373; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 374; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1 375; CHECK: [[VAL1:%[0-9]+]]:_(s64) = COPY $x2 376; CHECK: [[VAL2:%[0-9]+]]:_(s64) = COPY $x3 377; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16) 378; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42, addrspace 42) 379; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (volatile store 8 into %ir.addr) 380; CHECK: RET_ReallyLR 381define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) { 382 store i64 %val1, i64* %addr, align 16 383 store i64 %val2, i64 addrspace(42)* %addr42 384 store volatile i64 %val1, i64* %addr 385 %sum = add i64 %val1, %val2 386 ret void 387} 388 389; CHECK-LABEL: name: intrinsics 390; CHECK: [[CUR:%[0-9]+]]:_(s32) = COPY $w0 391; CHECK: [[BITS:%[0-9]+]]:_(s32) = COPY $w1 392; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0 393; CHECK: [[PTR_VEC:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr.vec 394; CHECK: [[VEC:%[0-9]+]]:_(<8 x s8>) = G_LOAD [[PTR_VEC]] 395; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0) 396; CHECK: RET_ReallyLR 397declare i8* @llvm.returnaddress(i32) 398declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*) 399declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0v8i8(<8 x i8>*) 400define void @intrinsics(i32 %cur, i32 %bits) { 401 %ptr = call i8* @llvm.returnaddress(i32 0) 402 %ptr.vec = alloca <8 x i8> 403 %vec = load <8 x i8>, <8 x i8>* %ptr.vec 404 call void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8> %vec, <8 x i8> %vec, i8* %ptr) 405 ret void 406} 407 408; CHECK-LABEL: name: test_phi 409; CHECK: G_BRCOND {{%.*}}, %[[TRUE:bb\.[0-9]+]] 410; CHECK: G_BR %[[FALSE:bb\.[0-9]+]] 411 412; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}: 413; CHECK: [[RES1:%[0-9]+]]:_(s32) = G_LOAD 414 415; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}: 416; CHECK: [[RES2:%[0-9]+]]:_(s32) = G_LOAD 417 418; CHECK: [[RES:%[0-9]+]]:_(s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]] 419; CHECK: $w0 = COPY [[RES]] 420define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) { 421 br i1 %tst, label %true, label %false 422 423true: 424 %res1 = load i32, i32* %addr1 425 br label %end 426 427false: 428 %res2 = load i32, i32* %addr2 429 br label %end 430 431end: 432 %res = phi i32 [%res1, %true], [%res2, %false] 433 ret i32 %res 434} 435 436; CHECK-LABEL: name: unreachable 437; CHECK: G_ADD 438; CHECK-NEXT: {{^$}} 439; CHECK-NEXT: ... 440define void @unreachable(i32 %a) { 441 %sum = add i32 %a, %a 442 unreachable 443} 444 445 ; It's important that constants are after argument passing, but before the 446 ; rest of the entry block. 447; CHECK-LABEL: name: constant_int 448; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0 449; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 450 451; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}: 452; CHECK: [[SUM1:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]] 453; CHECK: [[SUM2:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]] 454; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[SUM1]], [[SUM2]] 455; CHECK: $w0 = COPY [[RES]] 456 457define i32 @constant_int(i32 %in) { 458 br label %next 459 460next: 461 %sum1 = add i32 %in, 1 462 %sum2 = add i32 %in, 1 463 %res = add i32 %sum1, %sum2 464 ret i32 %res 465} 466 467; CHECK-LABEL: name: constant_int_start 468; CHECK: [[TWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 469; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42 470; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CONSTANT i32 44 471define i32 @constant_int_start() { 472 %res = add i32 2, 42 473 ret i32 %res 474} 475 476; CHECK-LABEL: name: test_undef 477; CHECK: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 478; CHECK: $w0 = COPY [[UNDEF]] 479define i32 @test_undef() { 480 ret i32 undef 481} 482 483; CHECK-LABEL: name: test_constant_inttoptr 484; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 485; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[ONE]] 486; CHECK: $x0 = COPY [[PTR]] 487define i8* @test_constant_inttoptr() { 488 ret i8* inttoptr(i64 1 to i8*) 489} 490 491 ; This failed purely because the Constant -> VReg map was kept across 492 ; functions, so reuse the "i64 1" from above. 493; CHECK-LABEL: name: test_reused_constant 494; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 495; CHECK: $x0 = COPY [[ONE]] 496define i64 @test_reused_constant() { 497 ret i64 1 498} 499 500; CHECK-LABEL: name: test_sext 501; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0 502; CHECK: [[RES:%[0-9]+]]:_(s64) = G_SEXT [[IN]] 503; CHECK: $x0 = COPY [[RES]] 504define i64 @test_sext(i32 %in) { 505 %res = sext i32 %in to i64 506 ret i64 %res 507} 508 509; CHECK-LABEL: name: test_zext 510; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0 511; CHECK: [[RES:%[0-9]+]]:_(s64) = G_ZEXT [[IN]] 512; CHECK: $x0 = COPY [[RES]] 513define i64 @test_zext(i32 %in) { 514 %res = zext i32 %in to i64 515 ret i64 %res 516} 517 518; CHECK-LABEL: name: test_shl 519; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 520; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 521; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SHL [[ARG1]], [[ARG2]] 522; CHECK-NEXT: $w0 = COPY [[RES]] 523; CHECK-NEXT: RET_ReallyLR implicit $w0 524define i32 @test_shl(i32 %arg1, i32 %arg2) { 525 %res = shl i32 %arg1, %arg2 526 ret i32 %res 527} 528 529 530; CHECK-LABEL: name: test_lshr 531; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 532; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 533; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_LSHR [[ARG1]], [[ARG2]] 534; CHECK-NEXT: $w0 = COPY [[RES]] 535; CHECK-NEXT: RET_ReallyLR implicit $w0 536define i32 @test_lshr(i32 %arg1, i32 %arg2) { 537 %res = lshr i32 %arg1, %arg2 538 ret i32 %res 539} 540 541; CHECK-LABEL: name: test_ashr 542; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 543; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 544; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_ASHR [[ARG1]], [[ARG2]] 545; CHECK-NEXT: $w0 = COPY [[RES]] 546; CHECK-NEXT: RET_ReallyLR implicit $w0 547define i32 @test_ashr(i32 %arg1, i32 %arg2) { 548 %res = ashr i32 %arg1, %arg2 549 ret i32 %res 550} 551 552; CHECK-LABEL: name: test_sdiv 553; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 554; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 555; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SDIV [[ARG1]], [[ARG2]] 556; CHECK-NEXT: $w0 = COPY [[RES]] 557; CHECK-NEXT: RET_ReallyLR implicit $w0 558define i32 @test_sdiv(i32 %arg1, i32 %arg2) { 559 %res = sdiv i32 %arg1, %arg2 560 ret i32 %res 561} 562 563; CHECK-LABEL: name: test_udiv 564; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 565; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 566; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UDIV [[ARG1]], [[ARG2]] 567; CHECK-NEXT: $w0 = COPY [[RES]] 568; CHECK-NEXT: RET_ReallyLR implicit $w0 569define i32 @test_udiv(i32 %arg1, i32 %arg2) { 570 %res = udiv i32 %arg1, %arg2 571 ret i32 %res 572} 573 574; CHECK-LABEL: name: test_srem 575; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 576; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 577; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SREM [[ARG1]], [[ARG2]] 578; CHECK-NEXT: $w0 = COPY [[RES]] 579; CHECK-NEXT: RET_ReallyLR implicit $w0 580define i32 @test_srem(i32 %arg1, i32 %arg2) { 581 %res = srem i32 %arg1, %arg2 582 ret i32 %res 583} 584 585; CHECK-LABEL: name: test_urem 586; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 587; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1 588; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UREM [[ARG1]], [[ARG2]] 589; CHECK-NEXT: $w0 = COPY [[RES]] 590; CHECK-NEXT: RET_ReallyLR implicit $w0 591define i32 @test_urem(i32 %arg1, i32 %arg2) { 592 %res = urem i32 %arg1, %arg2 593 ret i32 %res 594} 595 596; CHECK-LABEL: name: test_constant_null 597; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_CONSTANT i64 0 598; CHECK: $x0 = COPY [[NULL]] 599define i8* @test_constant_null() { 600 ret i8* null 601} 602 603; CHECK-LABEL: name: test_struct_memops 604; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 605; CHECK: [[VAL1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4) 606; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 607; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST1]](s64) 608; CHECK: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr + 4) 609; CHECK: G_STORE [[VAL1]](s8), [[ADDR]](p0) :: (store 1 into %ir.addr, align 4) 610; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST1]](s64) 611; CHECK: G_STORE [[VAL2]](s32), [[GEP2]](p0) :: (store 4 into %ir.addr + 4) 612define void @test_struct_memops({ i8, i32 }* %addr) { 613 %val = load { i8, i32 }, { i8, i32 }* %addr 614 store { i8, i32 } %val, { i8, i32 }* %addr 615 ret void 616} 617 618; CHECK-LABEL: name: test_i1_memops 619; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 620; CHECK: [[VAL:%[0-9]+]]:_(s1) = G_LOAD [[ADDR]](p0) :: (load 1 from %ir.addr) 621; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into %ir.addr) 622define void @test_i1_memops(i1* %addr) { 623 %val = load i1, i1* %addr 624 store i1 %val, i1* %addr 625 ret void 626} 627 628; CHECK-LABEL: name: int_comparison 629; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 630; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 631; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 632; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]] 633; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0) 634define void @int_comparison(i32 %a, i32 %b, i1* %addr) { 635 %res = icmp ne i32 %a, %b 636 store i1 %res, i1* %addr 637 ret void 638} 639 640; CHECK-LABEL: name: ptr_comparison 641; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x0 642; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x1 643; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 644; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LHS]](p0), [[RHS]] 645; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0) 646define void @ptr_comparison(i8* %a, i8* %b, i1* %addr) { 647 %res = icmp eq i8* %a, %b 648 store i1 %res, i1* %addr 649 ret void 650} 651 652; CHECK-LABEL: name: test_fadd 653; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 654; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1 655; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FADD [[ARG1]], [[ARG2]] 656; CHECK-NEXT: $s0 = COPY [[RES]] 657; CHECK-NEXT: RET_ReallyLR implicit $s0 658define float @test_fadd(float %arg1, float %arg2) { 659 %res = fadd float %arg1, %arg2 660 ret float %res 661} 662 663; CHECK-LABEL: name: test_fsub 664; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 665; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1 666; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FSUB [[ARG1]], [[ARG2]] 667; CHECK-NEXT: $s0 = COPY [[RES]] 668; CHECK-NEXT: RET_ReallyLR implicit $s0 669define float @test_fsub(float %arg1, float %arg2) { 670 %res = fsub float %arg1, %arg2 671 ret float %res 672} 673 674; CHECK-LABEL: name: test_fmul 675; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 676; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1 677; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FMUL [[ARG1]], [[ARG2]] 678; CHECK-NEXT: $s0 = COPY [[RES]] 679; CHECK-NEXT: RET_ReallyLR implicit $s0 680define float @test_fmul(float %arg1, float %arg2) { 681 %res = fmul float %arg1, %arg2 682 ret float %res 683} 684 685; CHECK-LABEL: name: test_fdiv 686; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 687; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1 688; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FDIV [[ARG1]], [[ARG2]] 689; CHECK-NEXT: $s0 = COPY [[RES]] 690; CHECK-NEXT: RET_ReallyLR implicit $s0 691define float @test_fdiv(float %arg1, float %arg2) { 692 %res = fdiv float %arg1, %arg2 693 ret float %res 694} 695 696; CHECK-LABEL: name: test_frem 697; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 698; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1 699; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FREM [[ARG1]], [[ARG2]] 700; CHECK-NEXT: $s0 = COPY [[RES]] 701; CHECK-NEXT: RET_ReallyLR implicit $s0 702define float @test_frem(float %arg1, float %arg2) { 703 %res = frem float %arg1, %arg2 704 ret float %res 705} 706 707; CHECK-LABEL: name: test_sadd_overflow 708; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 709; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 710; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 711; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SADDO [[LHS]], [[RHS]] 712; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr) 713; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 714; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64) 715; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4) 716declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) 717define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { 718 %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs) 719 store { i32, i1 } %res, { i32, i1 }* %addr 720 ret void 721} 722 723; CHECK-LABEL: name: test_uadd_overflow 724; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 725; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 726; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 727; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UADDO [[LHS]], [[RHS]] 728; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr) 729; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 730; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64) 731; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4) 732declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) 733define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { 734 %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs) 735 store { i32, i1 } %res, { i32, i1 }* %addr 736 ret void 737} 738 739; CHECK-LABEL: name: test_ssub_overflow 740; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 741; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 742; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 743; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SSUBO [[LHS]], [[RHS]] 744; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr) 745; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 746; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64) 747; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4) 748declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) 749define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) { 750 %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs) 751 store { i32, i1 } %res, { i32, i1 }* %subr 752 ret void 753} 754 755; CHECK-LABEL: name: test_usub_overflow 756; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 757; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 758; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 759; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_USUBO [[LHS]], [[RHS]] 760; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr) 761; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 762; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64) 763; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4) 764declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) 765define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) { 766 %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs) 767 store { i32, i1 } %res, { i32, i1 }* %subr 768 ret void 769} 770 771; CHECK-LABEL: name: test_smul_overflow 772; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 773; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 774; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 775; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SMULO [[LHS]], [[RHS]] 776; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr) 777; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 778; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64) 779; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4) 780declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) 781define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { 782 %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs) 783 store { i32, i1 } %res, { i32, i1 }* %addr 784 ret void 785} 786 787; CHECK-LABEL: name: test_umul_overflow 788; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0 789; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 790; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2 791; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UMULO [[LHS]], [[RHS]] 792; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr) 793; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 794; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64) 795; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4) 796declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) 797define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { 798 %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs) 799 store { i32, i1 } %res, { i32, i1 }* %addr 800 ret void 801} 802 803; CHECK-LABEL: name: test_extractvalue 804; CHECK: %0:_(p0) = COPY $x0 805; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4) 806; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 807; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64) 808; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4) 809; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 810; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64) 811; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8) 812; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12 813; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64) 814; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12) 815; CHECK: $w0 = COPY [[LD3]](s32) 816%struct.nested = type {i8, { i8, i32 }, i32} 817define i32 @test_extractvalue(%struct.nested* %addr) { 818 %struct = load %struct.nested, %struct.nested* %addr 819 %res = extractvalue %struct.nested %struct, 1, 1 820 ret i32 %res 821} 822 823; CHECK-LABEL: name: test_extractvalue_agg 824; CHECK: %0:_(p0) = COPY $x0 825; CHECK: %1:_(p0) = COPY $x1 826; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4) 827; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 828; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64) 829; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4) 830; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 831; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64) 832; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8) 833; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12 834; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64) 835; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12) 836; CHECK: G_STORE [[LD2]](s8), %1(p0) :: (store 1 into %ir.addr2, align 4) 837; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD %1, [[CST1]](s64) 838; CHECK: G_STORE [[LD3]](s32), [[GEP4]](p0) :: (store 4 into %ir.addr2 + 4) 839define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) { 840 %struct = load %struct.nested, %struct.nested* %addr 841 %res = extractvalue %struct.nested %struct, 1 842 store {i8, i32} %res, {i8, i32}* %addr2 843 ret void 844} 845 846; CHECK-LABEL: name: test_trivial_extract_ptr 847; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0 848; CHECK: [[VAL32:%[0-9]+]]:_(s32) = COPY $w1 849; CHECK: [[VAL:%[0-9]+]]:_(s8) = G_TRUNC [[VAL32]] 850; CHECK: G_STORE [[VAL]](s8), [[STRUCT]](p0) 851define void @test_trivial_extract_ptr([1 x i8*] %s, i8 %val) { 852 %addr = extractvalue [1 x i8*] %s, 0 853 store i8 %val, i8* %addr 854 ret void 855} 856 857; CHECK-LABEL: name: test_insertvalue 858; CHECK: %0:_(p0) = COPY $x0 859; CHECK: %1:_(s32) = COPY $w1 860; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4) 861; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 862; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64) 863; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4) 864; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 865; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64) 866; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8) 867; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12 868; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64) 869; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12) 870; CHECK: G_STORE [[LD1]](s8), %0(p0) :: (store 1 into %ir.addr, align 4) 871; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64) 872; CHECK: G_STORE [[LD2]](s8), [[GEP4]](p0) :: (store 1 into %ir.addr + 4, align 4) 873; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64) 874; CHECK: G_STORE %1(s32), [[GEP5]](p0) :: (store 4 into %ir.addr + 8) 875; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64) 876; CHECK: G_STORE [[LD4]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 12) 877define void @test_insertvalue(%struct.nested* %addr, i32 %val) { 878 %struct = load %struct.nested, %struct.nested* %addr 879 %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1 880 store %struct.nested %newstruct, %struct.nested* %addr 881 ret void 882} 883 884define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) { 885; CHECK-LABEL: name: test_trivial_insert 886; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0 887; CHECK: [[VAL:%[0-9]+]]:_(s64) = COPY $x1 888; CHECK: $x0 = COPY [[VAL]] 889 %res = insertvalue [1 x i64] %s, i64 %val, 0 890 ret [1 x i64] %res 891} 892 893define [1 x i8*] @test_trivial_insert_ptr([1 x i8*] %s, i8* %val) { 894; CHECK-LABEL: name: test_trivial_insert_ptr 895; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0 896; CHECK: [[VAL:%[0-9]+]]:_(p0) = COPY $x1 897; CHECK: $x0 = COPY [[VAL]] 898 %res = insertvalue [1 x i8*] %s, i8* %val, 0 899 ret [1 x i8*] %res 900} 901 902; CHECK-LABEL: name: test_insertvalue_agg 903; CHECK: %0:_(p0) = COPY $x0 904; CHECK: %1:_(p0) = COPY $x1 905; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %1(p0) :: (load 1 from %ir.addr2, align 4) 906; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 907; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %1, [[CST1]](s64) 908; CHECK: [[LD2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr2 + 4) 909; CHECK: [[LD3:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4) 910; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64) 911; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[GEP2]](p0) :: (load 1 from %ir.addr + 4, align 4) 912; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 913; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64) 914; CHECK: [[LD5:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 8) 915; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 12 916; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST4]](s64) 917; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.addr + 12) 918; CHECK: G_STORE [[LD3]](s8), %0(p0) :: (store 1 into %ir.addr, align 4) 919; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64) 920; CHECK: G_STORE [[LD1]](s8), [[GEP5]](p0) :: (store 1 into %ir.addr + 4, align 4) 921; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64) 922; CHECK: G_STORE [[LD2]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 8) 923; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST4]](s64) 924; CHECK: G_STORE [[LD6]](s32), [[GEP7]](p0) :: (store 4 into %ir.addr + 12) 925define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) { 926 %smallstruct = load {i8, i32}, {i8, i32}* %addr2 927 %struct = load %struct.nested, %struct.nested* %addr 928 %res = insertvalue %struct.nested %struct, {i8, i32} %smallstruct, 1 929 store %struct.nested %res, %struct.nested* %addr 930 ret void 931} 932 933; CHECK-LABEL: name: test_select 934; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0 935; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]] 936; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w1 937; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w2 938; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]] 939; CHECK: $w0 = COPY [[RES]] 940define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) { 941 %res = select i1 %tst, i32 %lhs, i32 %rhs 942 ret i32 %res 943} 944 945; CHECK-LABEL: name: test_select_flags 946; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 947; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32) 948; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $s0 949; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $s1 950; CHECK: [[SELECT:%[0-9]+]]:_(s32) = nnan G_SELECT [[TRUNC]](s1), [[COPY1]], [[COPY2]] 951define float @test_select_flags(i1 %tst, float %lhs, float %rhs) { 952 %res = select nnan i1 %tst, float %lhs, float %rhs 953 ret float %res 954} 955 956; Don't take the flags from the compare condition 957; CHECK-LABEL: name: test_select_cmp_flags 958; CHECK: [[COPY0:%[0-9]+]]:_(s32) = COPY $s0 959; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $s1 960; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $s2 961; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY $s3 962; CHECK: [[CMP:%[0-9]+]]:_(s1) = nsz G_FCMP floatpred(oeq), [[COPY0]](s32), [[COPY1]] 963; CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[CMP]](s1), [[COPY2]], [[COPY3]] 964define float @test_select_cmp_flags(float %cmp0, float %cmp1, float %lhs, float %rhs) { 965 %tst = fcmp nsz oeq float %cmp0, %cmp1 966 %res = select i1 %tst, float %lhs, float %rhs 967 ret float %res 968} 969 970; CHECK-LABEL: name: test_select_ptr 971; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0 972; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]] 973; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x1 974; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x2 975; CHECK: [[RES:%[0-9]+]]:_(p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]] 976; CHECK: $x0 = COPY [[RES]] 977define i8* @test_select_ptr(i1 %tst, i8* %lhs, i8* %rhs) { 978 %res = select i1 %tst, i8* %lhs, i8* %rhs 979 ret i8* %res 980} 981 982; CHECK-LABEL: name: test_select_vec 983; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0 984; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]] 985; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q0 986; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1 987; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]] 988; CHECK: $q0 = COPY [[RES]] 989define <4 x i32> @test_select_vec(i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs) { 990 %res = select i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs 991 ret <4 x i32> %res 992} 993 994; CHECK-LABEL: name: test_vselect_vec 995; CHECK: [[TST32:%[0-9]+]]:_(<4 x s32>) = COPY $q0 996; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1 997; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q2 998; CHECK: [[TST:%[0-9]+]]:_(<4 x s1>) = G_TRUNC [[TST32]](<4 x s32>) 999; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](<4 x s1>), [[LHS]], [[RHS]] 1000; CHECK: $q0 = COPY [[RES]] 1001define <4 x i32> @test_vselect_vec(<4 x i32> %tst32, <4 x i32> %lhs, <4 x i32> %rhs) { 1002 %tst = trunc <4 x i32> %tst32 to <4 x i1> 1003 %res = select <4 x i1> %tst, <4 x i32> %lhs, <4 x i32> %rhs 1004 ret <4 x i32> %res 1005} 1006 1007; CHECK-LABEL: name: test_fptosi 1008; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0 1009; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0) 1010; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOSI [[FP]](s32) 1011; CHECK: $x0 = COPY [[RES]] 1012define i64 @test_fptosi(float* %fp.addr) { 1013 %fp = load float, float* %fp.addr 1014 %res = fptosi float %fp to i64 1015 ret i64 %res 1016} 1017 1018; CHECK-LABEL: name: test_fptoui 1019; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0 1020; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0) 1021; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOUI [[FP]](s32) 1022; CHECK: $x0 = COPY [[RES]] 1023define i64 @test_fptoui(float* %fp.addr) { 1024 %fp = load float, float* %fp.addr 1025 %res = fptoui float %fp to i64 1026 ret i64 %res 1027} 1028 1029; CHECK-LABEL: name: test_sitofp 1030; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1031; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1 1032; CHECK: [[FP:%[0-9]+]]:_(s64) = G_SITOFP [[IN]](s32) 1033; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0) 1034define void @test_sitofp(double* %addr, i32 %in) { 1035 %fp = sitofp i32 %in to double 1036 store double %fp, double* %addr 1037 ret void 1038} 1039 1040; CHECK-LABEL: name: test_uitofp 1041; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1042; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1 1043; CHECK: [[FP:%[0-9]+]]:_(s64) = G_UITOFP [[IN]](s32) 1044; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0) 1045define void @test_uitofp(double* %addr, i32 %in) { 1046 %fp = uitofp i32 %in to double 1047 store double %fp, double* %addr 1048 ret void 1049} 1050 1051; CHECK-LABEL: name: test_fpext 1052; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $s0 1053; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPEXT [[IN]](s32) 1054; CHECK: $d0 = COPY [[RES]] 1055define double @test_fpext(float %in) { 1056 %res = fpext float %in to double 1057 ret double %res 1058} 1059 1060; CHECK-LABEL: name: test_fptrunc 1061; CHECK: [[IN:%[0-9]+]]:_(s64) = COPY $d0 1062; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FPTRUNC [[IN]](s64) 1063; CHECK: $s0 = COPY [[RES]] 1064define float @test_fptrunc(double %in) { 1065 %res = fptrunc double %in to float 1066 ret float %res 1067} 1068 1069; CHECK-LABEL: name: test_constant_float 1070; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1071; CHECK: [[TMP:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.500000e+00 1072; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0) 1073define void @test_constant_float(float* %addr) { 1074 store float 1.5, float* %addr 1075 ret void 1076} 1077 1078; CHECK-LABEL: name: float_comparison 1079; CHECK: [[LHSADDR:%[0-9]+]]:_(p0) = COPY $x0 1080; CHECK: [[RHSADDR:%[0-9]+]]:_(p0) = COPY $x1 1081; CHECK: [[BOOLADDR:%[0-9]+]]:_(p0) = COPY $x2 1082; CHECK: [[LHS:%[0-9]+]]:_(s32) = G_LOAD [[LHSADDR]](p0) 1083; CHECK: [[RHS:%[0-9]+]]:_(s32) = G_LOAD [[RHSADDR]](p0) 1084; CHECK: [[TST:%[0-9]+]]:_(s1) = nnan ninf nsz arcp contract afn reassoc G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]] 1085; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0) 1086define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) { 1087 %a = load float, float* %a.addr 1088 %b = load float, float* %b.addr 1089 %res = fcmp nnan ninf nsz arcp contract afn reassoc oge float %a, %b 1090 store i1 %res, i1* %bool.addr 1091 ret void 1092} 1093 1094; CHECK-LABEL: name: trivial_float_comparison 1095; CHECK: [[ENTRY_R1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false 1096; CHECK: [[ENTRY_R2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true 1097; CHECK: [[R1:%[0-9]+]]:_(s1) = COPY [[ENTRY_R1]](s1) 1098; CHECK: [[R2:%[0-9]+]]:_(s1) = COPY [[ENTRY_R2]](s1) 1099; CHECK: G_ADD [[R1]], [[R2]] 1100define i1 @trivial_float_comparison(double %a, double %b) { 1101 %r1 = fcmp false double %a, %b 1102 %r2 = fcmp true double %a, %b 1103 %sum = add i1 %r1, %r2 1104 ret i1 %sum 1105} 1106 1107@var = global i32 0 1108 1109define i32* @test_global() { 1110; CHECK-LABEL: name: test_global 1111; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var{{$}} 1112; CHECK: $x0 = COPY [[TMP]](p0) 1113 1114 ret i32* @var 1115} 1116 1117@var1 = addrspace(42) global i32 0 1118define i32 addrspace(42)* @test_global_addrspace() { 1119; CHECK-LABEL: name: test_global 1120; CHECK: [[TMP:%[0-9]+]]:_(p42) = G_GLOBAL_VALUE @var1{{$}} 1121; CHECK: $x0 = COPY [[TMP]](p42) 1122 1123 ret i32 addrspace(42)* @var1 1124} 1125 1126 1127define void()* @test_global_func() { 1128; CHECK-LABEL: name: test_global_func 1129; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @allocai64{{$}} 1130; CHECK: $x0 = COPY [[TMP]](p0) 1131 1132 ret void()* @allocai64 1133} 1134 1135declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) 1136define void @test_memcpy(i8* %dst, i8* %src, i64 %size) { 1137; CHECK-LABEL: name: test_memcpy 1138; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0 1139; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1 1140; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2 1141; CHECK: G_MEMCPY [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 0 :: (store 1 into %ir.dst), (load 1 from %ir.src) 1142 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0) 1143 ret void 1144} 1145 1146define void @test_memcpy_tail(i8* %dst, i8* %src, i64 %size) { 1147; CHECK-LABEL: name: test_memcpy_tail 1148; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0 1149; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1 1150; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2 1151; CHECK: G_MEMCPY [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 1 :: (store 1 into %ir.dst), (load 1 from %ir.src) 1152 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0) 1153 ret void 1154} 1155 1156declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)*, i8 addrspace(1)*, i64, i1) 1157define void @test_memcpy_nonzero_as(i8 addrspace(1)* %dst, i8 addrspace(1) * %src, i64 %size) { 1158; CHECK-LABEL: name: test_memcpy_nonzero_as 1159; CHECK: [[DST:%[0-9]+]]:_(p1) = COPY $x0 1160; CHECK: [[SRC:%[0-9]+]]:_(p1) = COPY $x1 1161; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2 1162; CHECK: G_MEMCPY [[DST]](p1), [[SRC]](p1), [[SIZE]](s64), 0 :: (store 1 into %ir.dst, addrspace 1), (load 1 from %ir.src, addrspace 1) 1163 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 %size, i1 0) 1164 ret void 1165} 1166 1167declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i1) 1168define void @test_memmove(i8* %dst, i8* %src, i64 %size) { 1169; CHECK-LABEL: name: test_memmove 1170; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0 1171; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1 1172; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2 1173; CHECK: G_MEMMOVE [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 0 :: (store 1 into %ir.dst), (load 1 from %ir.src) 1174 call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0) 1175 ret void 1176} 1177 1178declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1) 1179define void @test_memset(i8* %dst, i8 %val, i64 %size) { 1180; CHECK-LABEL: name: test_memset 1181; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0 1182; CHECK: [[SRC_C:%[0-9]+]]:_(s32) = COPY $w1 1183; CHECK: [[SRC:%[0-9]+]]:_(s8) = G_TRUNC [[SRC_C]] 1184; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2 1185; CHECK: G_MEMSET [[DST]](p0), [[SRC]](s8), [[SIZE]](s64), 0 :: (store 1 into %ir.dst) 1186 call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i1 0) 1187 ret void 1188} 1189 1190define void @test_large_const(i128* %addr) { 1191; CHECK-LABEL: name: test_large_const 1192; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1193; CHECK: [[VAL:%[0-9]+]]:_(s128) = G_CONSTANT i128 42 1194; CHECK: G_STORE [[VAL]](s128), [[ADDR]](p0) 1195 store i128 42, i128* %addr 1196 ret void 1197} 1198 1199; When there was no formal argument handling (so the first BB was empty) we used 1200; to insert the constants at the end of the block, even if they were encountered 1201; after the block's terminators had been emitted. Also make sure the order is 1202; correct. 1203define i8* @test_const_placement() { 1204; CHECK-LABEL: name: test_const_placement 1205; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}): 1206; CHECK: [[VAL_INT:%[0-9]+]]:_(s32) = G_CONSTANT i32 42 1207; CHECK: [[VAL:%[0-9]+]]:_(p0) = G_INTTOPTR [[VAL_INT]](s32) 1208; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}: 1209 br label %next 1210 1211next: 1212 ret i8* inttoptr(i32 42 to i8*) 1213} 1214 1215declare void @llvm.va_end(i8*) 1216define void @test_va_end(i8* %list) { 1217; CHECK-LABEL: name: test_va_end 1218; CHECK-NOT: va_end 1219; CHECK-NOT: INTRINSIC 1220; CHECK: RET_ReallyLR 1221 call void @llvm.va_end(i8* %list) 1222 ret void 1223} 1224 1225define void @test_va_arg(i8* %list) { 1226; CHECK-LABEL: test_va_arg 1227; CHECK: [[LIST:%[0-9]+]]:_(p0) = COPY $x0 1228; CHECK: G_VAARG [[LIST]](p0), 8 1229; CHECK: G_VAARG [[LIST]](p0), 1 1230; CHECK: G_VAARG [[LIST]](p0), 16 1231 1232 %v0 = va_arg i8* %list, i64 1233 %v1 = va_arg i8* %list, i8 1234 %v2 = va_arg i8* %list, i128 1235 ret void 1236} 1237 1238declare float @llvm.pow.f32(float, float) 1239define float @test_pow_intrin(float %l, float %r) { 1240; CHECK-LABEL: name: test_pow_intrin 1241; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0 1242; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $s1 1243; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOW [[LHS]], [[RHS]] 1244; CHECK: $s0 = COPY [[RES]] 1245 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.pow.f32(float %l, float %r) 1246 ret float %res 1247} 1248 1249declare float @llvm.powi.f32(float, i32) 1250define float @test_powi_intrin(float %l, i32 %r) { 1251; CHECK-LABEL: name: test_powi_intrin 1252; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0 1253; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w0 1254; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOWI [[LHS]], [[RHS]] 1255; CHECK: $s0 = COPY [[RES]] 1256 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.powi.f32(float %l, i32 %r) 1257 ret float %res 1258} 1259 1260declare float @llvm.fma.f32(float, float, float) 1261define float @test_fma_intrin(float %a, float %b, float %c) { 1262; CHECK-LABEL: name: test_fma_intrin 1263; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1264; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1 1265; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $s2 1266; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FMA [[A]], [[B]], [[C]] 1267; CHECK: $s0 = COPY [[RES]] 1268 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fma.f32(float %a, float %b, float %c) 1269 ret float %res 1270} 1271 1272declare float @llvm.exp.f32(float) 1273define float @test_exp_intrin(float %a) { 1274; CHECK-LABEL: name: test_exp_intrin 1275; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1276; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP [[A]] 1277; CHECK: $s0 = COPY [[RES]] 1278 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp.f32(float %a) 1279 ret float %res 1280} 1281 1282declare float @llvm.exp2.f32(float) 1283define float @test_exp2_intrin(float %a) { 1284; CHECK-LABEL: name: test_exp2_intrin 1285; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1286; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP2 [[A]] 1287; CHECK: $s0 = COPY [[RES]] 1288 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp2.f32(float %a) 1289 ret float %res 1290} 1291 1292declare float @llvm.log.f32(float) 1293define float @test_log_intrin(float %a) { 1294; CHECK-LABEL: name: test_log_intrin 1295; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1296; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG [[A]] 1297; CHECK: $s0 = COPY [[RES]] 1298 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log.f32(float %a) 1299 ret float %res 1300} 1301 1302declare float @llvm.log2.f32(float) 1303define float @test_log2_intrin(float %a) { 1304; CHECK-LABEL: name: test_log2_intrin 1305; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1306; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FLOG2 [[A]] 1307; CHECK: $s0 = COPY [[RES]] 1308 %res = call float @llvm.log2.f32(float %a) 1309 ret float %res 1310} 1311 1312declare float @llvm.log10.f32(float) 1313define float @test_log10_intrin(float %a) { 1314; CHECK-LABEL: name: test_log10_intrin 1315; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1316; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG10 [[A]] 1317; CHECK: $s0 = COPY [[RES]] 1318 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log10.f32(float %a) 1319 ret float %res 1320} 1321 1322declare float @llvm.fabs.f32(float) 1323define float @test_fabs_intrin(float %a) { 1324; CHECK-LABEL: name: test_fabs_intrin 1325; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1326; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FABS [[A]] 1327; CHECK: $s0 = COPY [[RES]] 1328 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fabs.f32(float %a) 1329 ret float %res 1330} 1331 1332declare float @llvm.copysign.f32(float, float) 1333define float @test_fcopysign_intrin(float %a, float %b) { 1334; CHECK-LABEL: name: test_fcopysign_intrin 1335; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1336; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1 1337; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCOPYSIGN [[A]], [[B]] 1338; CHECK: $s0 = COPY [[RES]] 1339 1340 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.copysign.f32(float %a, float %b) 1341 ret float %res 1342} 1343 1344declare float @llvm.canonicalize.f32(float) 1345define float @test_fcanonicalize_intrin(float %a) { 1346; CHECK-LABEL: name: test_fcanonicalize_intrin 1347; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1348; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCANONICALIZE [[A]] 1349; CHECK: $s0 = COPY [[RES]] 1350 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.canonicalize.f32(float %a) 1351 ret float %res 1352} 1353 1354declare float @llvm.trunc.f32(float) 1355define float @test_intrinsic_trunc(float %a) { 1356; CHECK-LABEL: name: test_intrinsic_trunc 1357; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1358; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_TRUNC [[A]] 1359; CHECK: $s0 = COPY [[RES]] 1360 %res = call float @llvm.trunc.f32(float %a) 1361 ret float %res 1362} 1363 1364declare float @llvm.round.f32(float) 1365define float @test_intrinsic_round(float %a) { 1366; CHECK-LABEL: name: test_intrinsic_round 1367; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1368; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_ROUND [[A]] 1369; CHECK: $s0 = COPY [[RES]] 1370 %res = call float @llvm.round.f32(float %a) 1371 ret float %res 1372} 1373 1374declare i32 @llvm.lrint.i32.f32(float) 1375define i32 @test_intrinsic_lrint(float %a) { 1376; CHECK-LABEL: name: test_intrinsic_lrint 1377; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0 1378; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_LRINT [[A]] 1379; CHECK: $w0 = COPY [[RES]] 1380 %res = call i32 @llvm.lrint.i32.f32(float %a) 1381 ret i32 %res 1382} 1383 1384declare i32 @llvm.ctlz.i32(i32, i1) 1385define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) { 1386; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef 1387; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0 1388; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]] 1389; CHECK: $w0 = COPY [[RES]] 1390 %res = call i32 @llvm.ctlz.i32(i32 %a, i1 0) 1391 ret i32 %res 1392} 1393 1394declare i32 @llvm.cttz.i32(i32, i1) 1395define i32 @test_cttz_intrinsic_zero_undef(i32 %a) { 1396; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef 1397; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0 1398; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]] 1399; CHECK: $w0 = COPY [[RES]] 1400 %res = call i32 @llvm.cttz.i32(i32 %a, i1 1) 1401 ret i32 %res 1402} 1403 1404declare i32 @llvm.ctpop.i32(i32) 1405define i32 @test_ctpop_intrinsic(i32 %a) { 1406; CHECK-LABEL: name: test_ctpop 1407; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0 1408; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]] 1409; CHECK: $w0 = COPY [[RES]] 1410 %res = call i32 @llvm.ctpop.i32(i32 %a) 1411 ret i32 %res 1412} 1413 1414declare i32 @llvm.bitreverse.i32(i32) 1415define i32 @test_bitreverse_intrinsic(i32 %a) { 1416; CHECK-LABEL: name: test_bitreverse 1417; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0 1418; CHECK: [[RES:%[0-9]+]]:_(s32) = G_BITREVERSE [[A]] 1419; CHECK: $w0 = COPY [[RES]] 1420 %res = call i32 @llvm.bitreverse.i32(i32 %a) 1421 ret i32 %res 1422} 1423 1424declare i32 @llvm.fshl.i32(i32, i32, i32) 1425define i32 @test_fshl_intrinsic(i32 %a, i32 %b, i32 %c) { 1426; CHECK-LABEL: name: test_fshl_intrinsic 1427; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0 1428; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $w1 1429; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $w2 1430; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FSHL [[A]], [[B]], [[C]] 1431; CHECK: $w0 = COPY [[RES]] 1432 %res = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c) 1433 ret i32 %res 1434} 1435 1436declare i32 @llvm.fshr.i32(i32, i32, i32) 1437define i32 @test_fshr_intrinsic(i32 %a, i32 %b, i32 %c) { 1438; CHECK-LABEL: name: test_fshr_intrinsic 1439; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0 1440; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $w1 1441; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $w2 1442; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FSHR [[A]], [[B]], [[C]] 1443; CHECK: $w0 = COPY [[RES]] 1444 %res = call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c) 1445 ret i32 %res 1446} 1447 1448declare void @llvm.lifetime.start.p0i8(i64, i8*) 1449declare void @llvm.lifetime.end.p0i8(i64, i8*) 1450define void @test_lifetime_intrin() { 1451; CHECK-LABEL: name: test_lifetime_intrin 1452; CHECK: RET_ReallyLR 1453; O3-LABEL: name: test_lifetime_intrin 1454; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot 1455; O3-NEXT: LIFETIME_START %stack.0.slot 1456; O3-NEXT: LIFETIME_END %stack.0.slot 1457; O3-NEXT: RET_ReallyLR 1458 %slot = alloca i8, i32 4 1459 call void @llvm.lifetime.start.p0i8(i64 0, i8* %slot) 1460 call void @llvm.lifetime.end.p0i8(i64 0, i8* %slot) 1461 ret void 1462} 1463 1464define void @test_load_store_atomics(i8* %addr) { 1465; CHECK-LABEL: name: test_load_store_atomics 1466; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1467; CHECK: [[V0:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load unordered 1 from %ir.addr) 1468; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic 1 into %ir.addr) 1469; CHECK: [[V1:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load acquire 1 from %ir.addr) 1470; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release 1 into %ir.addr) 1471; CHECK: [[V2:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load syncscope("singlethread") seq_cst 1 from %ir.addr) 1472; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store syncscope("singlethread") monotonic 1 into %ir.addr) 1473 %v0 = load atomic i8, i8* %addr unordered, align 1 1474 store atomic i8 %v0, i8* %addr monotonic, align 1 1475 1476 %v1 = load atomic i8, i8* %addr acquire, align 1 1477 store atomic i8 %v1, i8* %addr release, align 1 1478 1479 %v2 = load atomic i8, i8* %addr syncscope("singlethread") seq_cst, align 1 1480 store atomic i8 %v2, i8* %addr syncscope("singlethread") monotonic, align 1 1481 1482 ret void 1483} 1484 1485define float @test_fneg_f32(float %x) { 1486; CHECK-LABEL: name: test_fneg_f32 1487; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0 1488; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]] 1489; CHECK: $s0 = COPY [[RES]](s32) 1490 %neg = fneg float %x 1491 ret float %neg 1492} 1493 1494define float @test_fneg_f32_fmf(float %x) { 1495; CHECK-LABEL: name: test_fneg_f32 1496; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0 1497; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]] 1498; CHECK: $s0 = COPY [[RES]](s32) 1499 %neg = fneg fast float %x 1500 ret float %neg 1501} 1502 1503define double @test_fneg_f64(double %x) { 1504; CHECK-LABEL: name: test_fneg_f64 1505; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0 1506; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]] 1507; CHECK: $d0 = COPY [[RES]](s64) 1508 %neg = fneg double %x 1509 ret double %neg 1510} 1511 1512define double @test_fneg_f64_fmf(double %x) { 1513; CHECK-LABEL: name: test_fneg_f64 1514; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0 1515; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]] 1516; CHECK: $d0 = COPY [[RES]](s64) 1517 %neg = fneg fast double %x 1518 ret double %neg 1519} 1520 1521define void @test_trivial_inlineasm() { 1522; CHECK-LABEL: name: test_trivial_inlineasm 1523; CHECK: INLINEASM &wibble, 1 1524; CHECK: INLINEASM &wibble, 0 1525 call void asm sideeffect "wibble", ""() 1526 call void asm "wibble", ""() 1527 ret void 1528} 1529 1530define <2 x i32> @test_insertelement(<2 x i32> %vec, i32 %elt, i32 %idx){ 1531; CHECK-LABEL: name: test_insertelement 1532; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1533; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0 1534; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w1 1535; CHECK: [[RES:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[VEC]], [[ELT]](s32), [[IDX]](s32) 1536; CHECK: $d0 = COPY [[RES]](<2 x s32>) 1537 %res = insertelement <2 x i32> %vec, i32 %elt, i32 %idx 1538 ret <2 x i32> %res 1539} 1540 1541define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) { 1542; CHECK-LABEL: name: test_extractelement 1543; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1544; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0 1545; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_SEXT [[IDX]] 1546; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64) 1547; CHECK: $w0 = COPY [[RES]](s32) 1548 %res = extractelement <2 x i32> %vec, i32 %idx 1549 ret i32 %res 1550} 1551 1552define i32 @test_extractelement_const_idx(<2 x i32> %vec) { 1553; CHECK-LABEL: name: test_extractelement 1554; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1555; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 1556; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64) 1557; CHECK: $w0 = COPY [[RES]](s32) 1558 %res = extractelement <2 x i32> %vec, i32 1 1559 ret i32 %res 1560} 1561 1562define i32 @test_singleelementvector(i32 %elt){ 1563; CHECK-LABEL: name: test_singleelementvector 1564; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0 1565; CHECK-NOT: G_INSERT_VECTOR_ELT 1566; CHECK-NOT: G_EXTRACT_VECTOR_ELT 1567; CHECK: $w0 = COPY [[ELT]](s32) 1568 %vec = insertelement <1 x i32> undef, i32 %elt, i32 0 1569 %res = extractelement <1 x i32> %vec, i32 0 1570 ret i32 %res 1571} 1572 1573define <2 x i32> @test_constantaggzerovector_v2i32() { 1574; CHECK-LABEL: name: test_constantaggzerovector_v2i32 1575; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 1576; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32) 1577; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1578 ret <2 x i32> zeroinitializer 1579} 1580 1581define <2 x float> @test_constantaggzerovector_v2f32() { 1582; CHECK-LABEL: name: test_constantaggzerovector_v2f32 1583; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_FCONSTANT float 0.000000e+00 1584; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32) 1585; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1586 ret <2 x float> zeroinitializer 1587} 1588 1589define i32 @test_constantaggzerovector_v3i32() { 1590; CHECK-LABEL: name: test_constantaggzerovector_v3i32 1591; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 1592; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32), [[ZERO]](s32) 1593; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>) 1594 %elt = extractelement <3 x i32> zeroinitializer, i32 1 1595 ret i32 %elt 1596} 1597 1598define <2 x i32> @test_constantdatavector_v2i32() { 1599; CHECK-LABEL: name: test_constantdatavector_v2i32 1600; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1601; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 1602; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32) 1603; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1604 ret <2 x i32> <i32 1, i32 2> 1605} 1606 1607define i32 @test_constantdatavector_v3i32() { 1608; CHECK-LABEL: name: test_constantdatavector_v3i32 1609; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1610; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 1611; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3 1612; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32) 1613; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>) 1614 %elt = extractelement <3 x i32> <i32 1, i32 2, i32 3>, i32 1 1615 ret i32 %elt 1616} 1617 1618define <4 x i32> @test_constantdatavector_v4i32() { 1619; CHECK-LABEL: name: test_constantdatavector_v4i32 1620; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1621; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 1622; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3 1623; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 1624; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32), [[C4]](s32) 1625; CHECK: $q0 = COPY [[VEC]](<4 x s32>) 1626 ret <4 x i32> <i32 1, i32 2, i32 3, i32 4> 1627} 1628 1629define <2 x double> @test_constantdatavector_v2f64() { 1630; CHECK-LABEL: name: test_constantdatavector_v2f64 1631; CHECK: [[FC1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00 1632; CHECK: [[FC2:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00 1633; CHECK: [[VEC:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[FC1]](s64), [[FC2]](s64) 1634; CHECK: $q0 = COPY [[VEC]](<2 x s64>) 1635 ret <2 x double> <double 1.0, double 2.0> 1636} 1637 1638define i32 @test_constantaggzerovector_v1s32(i32 %arg){ 1639; CHECK-LABEL: name: test_constantaggzerovector_v1s32 1640; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0 1641; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 1642; CHECK-NOT: G_MERGE_VALUES 1643; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C0]] 1644; CHECK-NOT: G_MERGE_VALUES 1645; CHECK: G_ADD [[ARG]], [[COPY]] 1646 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0 1647 %add = add <1 x i32> %vec, zeroinitializer 1648 %res = extractelement <1 x i32> %add, i32 0 1649 ret i32 %res 1650} 1651 1652define i32 @test_constantdatavector_v1s32(i32 %arg){ 1653; CHECK-LABEL: name: test_constantdatavector_v1s32 1654; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0 1655; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1656; CHECK-NOT: G_MERGE_VALUES 1657; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C0]] 1658; CHECK-NOT: G_MERGE_VALUES 1659; CHECK: G_ADD [[ARG]], [[COPY]] 1660 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0 1661 %add = add <1 x i32> %vec, <i32 1> 1662 %res = extractelement <1 x i32> %add, i32 0 1663 ret i32 %res 1664} 1665 1666declare ghccc float @different_call_conv_target(float %x) 1667define float @test_different_call_conv_target(float %x) { 1668; CHECK-LABEL: name: test_different_call_conv 1669; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0 1670; CHECK: $s8 = COPY [[X]] 1671; CHECK: BL @different_call_conv_target, csr_aarch64_noregs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0 1672 %res = call ghccc float @different_call_conv_target(float %x) 1673 ret float %res 1674} 1675 1676define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) { 1677; CHECK-LABEL: name: test_shufflevector_s32_v2s32 1678; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0 1679; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF 1680; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0) 1681; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1682 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0 1683 %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer 1684 ret <2 x i32> %res 1685} 1686 1687define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) { 1688; CHECK-LABEL: name: test_shufflevector_v2s32_s32 1689; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1690; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1) 1691; CHECK: $w0 = COPY [[RES]](s32) 1692 %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1> 1693 %res = extractelement <1 x i32> %vec, i32 0 1694 ret i32 %res 1695} 1696 1697define <2 x i32> @test_shufflevector_v2s32_v2s32_undef(<2 x i32> %arg) { 1698; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef 1699; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1700; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1701; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, undef) 1702; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1703 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> undef 1704 ret <2 x i32> %res 1705} 1706 1707define <2 x i32> @test_shufflevector_v2s32_v2s32_undef_0(<2 x i32> %arg) { 1708; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef_0 1709; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1710; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1711; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, 0) 1712; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1713 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 undef, i32 0> 1714 ret <2 x i32> %res 1715} 1716 1717define <2 x i32> @test_shufflevector_v2s32_v2s32_0_undef(<2 x i32> %arg) { 1718; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_0_undef 1719; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1720; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1721; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(0, undef) 1722; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1723 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 0, i32 undef> 1724 ret <2 x i32> %res 1725} 1726 1727define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) { 1728; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32 1729; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1730; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF 1731; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1) 1732; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>) 1733 %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1> 1734 %res = extractelement <3 x i32> %vec, i32 0 1735 ret i32 %res 1736} 1737 1738define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) { 1739; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32 1740; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0 1741; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1 1742; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], shufflemask(0, 1, 2, 3) 1743; CHECK: $q0 = COPY [[VEC]](<4 x s32>) 1744 %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1745 ret <4 x i32> %res 1746} 1747 1748define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) { 1749; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32 1750; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0 1751; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF 1752; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], shufflemask(1, 3) 1753; CHECK: $d0 = COPY [[VEC]](<2 x s32>) 1754 %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3> 1755 ret <2 x i32> %res 1756} 1757 1758 1759define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) { 1760; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8 1761; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0 1762; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1 1763; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], shufflemask(0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15) 1764; CHECK: $q0 = COPY [[VEC]](<16 x s8>) 1765 %res = shufflevector <8 x i8> %arg1, <8 x i8> %arg2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15> 1766 ret <16 x i8> %res 1767} 1768 1769; CHECK-LABEL: test_constant_vector 1770; CHECK: [[UNDEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF 1771; CHECK: [[F:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH3C00 1772; CHECK: [[M:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UNDEF]](s16), [[UNDEF]](s16), [[UNDEF]](s16), [[F]](s16) 1773; CHECK: $d0 = COPY [[M]](<4 x s16>) 1774define <4 x half> @test_constant_vector() { 1775 ret <4 x half> <half undef, half undef, half undef, half 0xH3C00> 1776} 1777 1778define i32 @test_target_mem_intrinsic(i32* %addr) { 1779; CHECK-LABEL: name: test_target_mem_intrinsic 1780; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1781; CHECK: [[VAL:%[0-9]+]]:_(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), [[ADDR]](p0) :: (volatile load 4 from %ir.addr) 1782; CHECK: G_TRUNC [[VAL]](s64) 1783 %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr) 1784 %trunc = trunc i64 %val to i32 1785 ret i32 %trunc 1786} 1787 1788declare i64 @llvm.aarch64.ldxr.p0i32(i32*) nounwind 1789 1790%zerosize_type = type {} 1791 1792define %zerosize_type @test_empty_load_store(%zerosize_type *%ptr, %zerosize_type %in) noinline optnone { 1793; CHECK-LABEL: name: test_empty_load_store 1794; CHECK-NOT: G_STORE 1795; CHECK-NOT: G_LOAD 1796; CHECK: RET_ReallyLR 1797entry: 1798 store %zerosize_type undef, %zerosize_type* undef, align 4 1799 %val = load %zerosize_type, %zerosize_type* %ptr, align 4 1800 ret %zerosize_type %in 1801} 1802 1803 1804define i64 @test_phi_loop(i32 %n) { 1805; CHECK-LABEL: name: test_phi_loop 1806; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0 1807; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1808; CHECK: [[CST2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 1809; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 1810; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 1811 1812; CHECK: [[PN1:%[0-9]+]]:_(s32) = G_PHI [[ARG1]](s32), %bb.1, [[SUB:%[0-9]+]](s32), %bb.2 1813; CHECK: [[PN2:%[0-9]+]]:_(s64) = G_PHI [[CST3]](s64), %bb.1, [[PN3:%[0-9]+]](s64), %bb.2 1814; CHECK: [[PN3]]:_(s64) = G_PHI [[CST4]](s64), %bb.1, [[ADD:%[0-9]+]](s64), %bb.2 1815; CHECK: [[ADD]]:_(s64) = G_ADD [[PN2]], [[PN3]] 1816; CHECK: [[SUB]]:_(s32) = G_SUB [[PN1]], [[CST1]] 1817; CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[PN1]](s32), [[CST2]] 1818; CHECK: G_BRCOND [[CMP]](s1), %bb.3 1819; CHECK: G_BR %bb.2 1820 1821; CHECK: $x0 = COPY [[PN2]](s64) 1822; CHECK: RET_ReallyLR implicit $x0 1823entry: 1824 br label %loop 1825 1826loop: 1827 %counter = phi i32 [ %n, %entry ], [ %counter.dec, %loop ] 1828 %elem = phi { i64, i64 } [ { i64 0, i64 1 }, %entry ], [ %updated, %loop ] 1829 %prev = extractvalue { i64, i64 } %elem, 0 1830 %curr = extractvalue { i64, i64 } %elem, 1 1831 %next = add i64 %prev, %curr 1832 %shifted = insertvalue { i64, i64 } %elem, i64 %curr, 0 1833 %updated = insertvalue { i64, i64 } %shifted, i64 %next, 1 1834 %counter.dec = sub i32 %counter, 1 1835 %cond = icmp sle i32 %counter, 0 1836 br i1 %cond, label %exit, label %loop 1837 1838exit: 1839 %res = extractvalue { i64, i64 } %elem, 0 1840 ret i64 %res 1841} 1842 1843define void @test_phi_diamond({ i8, i16, i32 }* %a.ptr, { i8, i16, i32 }* %b.ptr, i1 %selector, { i8, i16, i32 }* %dst) { 1844; CHECK-LABEL: name: test_phi_diamond 1845; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0 1846; CHECK: [[ARG2:%[0-9]+]]:_(p0) = COPY $x1 1847; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $w2 1848; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARG3]](s32) 1849; CHECK: [[ARG4:%[0-9]+]]:_(p0) = COPY $x3 1850; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2 1851; CHECK: G_BR %bb.3 1852 1853; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD [[ARG1]](p0) :: (load 1 from %ir.a.ptr, align 4) 1854; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2 1855; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG1]], [[CST1]](s64) 1856; CHECK: [[LD2:%[0-9]+]]:_(s16) = G_LOAD [[GEP1]](p0) :: (load 2 from %ir.a.ptr + 2) 1857; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 1858; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG1]], [[CST2]](s64) 1859; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.a.ptr + 4) 1860; CHECK: G_BR %bb.4 1861 1862; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[ARG2]](p0) :: (load 1 from %ir.b.ptr, align 4) 1863; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2 1864; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG2]], [[CST3]](s64) 1865; CHECK: [[LD5:%[0-9]+]]:_(s16) = G_LOAD [[GEP3]](p0) :: (load 2 from %ir.b.ptr + 2) 1866; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 1867; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG2]], [[CST4]](s64) 1868; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.b.ptr + 4) 1869 1870; CHECK: [[PN1:%[0-9]+]]:_(s8) = G_PHI [[LD1]](s8), %bb.2, [[LD4]](s8), %bb.3 1871; CHECK: [[PN2:%[0-9]+]]:_(s16) = G_PHI [[LD2]](s16), %bb.2, [[LD5]](s16), %bb.3 1872; CHECK: [[PN3:%[0-9]+]]:_(s32) = G_PHI [[LD3]](s32), %bb.2, [[LD6]](s32), %bb.3 1873; CHECK: G_STORE [[PN1]](s8), [[ARG4]](p0) :: (store 1 into %ir.dst, align 4) 1874; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 2 1875; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG4]], [[CST5]](s64) 1876; CHECK: G_STORE [[PN2]](s16), [[GEP5]](p0) :: (store 2 into %ir.dst + 2) 1877; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 1878; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG4]], [[CST6]](s64) 1879; CHECK: G_STORE [[PN3]](s32), [[GEP6]](p0) :: (store 4 into %ir.dst + 4) 1880; CHECK: RET_ReallyLR 1881 1882entry: 1883 br i1 %selector, label %store.a, label %store.b 1884 1885store.a: 1886 %a = load { i8, i16, i32 }, { i8, i16, i32 }* %a.ptr 1887 br label %join 1888 1889store.b: 1890 %b = load { i8, i16, i32 }, { i8, i16, i32 }* %b.ptr 1891 br label %join 1892 1893join: 1894 %v = phi { i8, i16, i32 } [ %a, %store.a ], [ %b, %store.b ] 1895 store { i8, i16, i32 } %v, { i8, i16, i32 }* %dst 1896 ret void 1897} 1898 1899%agg.inner.inner = type {i64, i64} 1900%agg.inner = type {i16, i8, %agg.inner.inner } 1901%agg.nested = type {i32, i32, %agg.inner, i32} 1902 1903define void @test_nested_aggregate_const(%agg.nested *%ptr) { 1904; CHECK-LABEL: name: test_nested_aggregate_const 1905; CHECK: [[BASE:%[0-9]+]]:_(p0) = COPY $x0 1906; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1907; CHECK: [[CST2:%[0-9]+]]:_(s16) = G_CONSTANT i16 2 1908; CHECK: [[CST3:%[0-9]+]]:_(s8) = G_CONSTANT i8 3 1909; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5 1910; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 1911; CHECK: [[CST6:%[0-9]+]]:_(s32) = G_CONSTANT i32 13 1912; CHECK: G_STORE [[CST1]](s32), [[BASE]](p0) :: (store 4 into %ir.ptr, align 8) 1913; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 1914; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST7]](s64) 1915; CHECK: G_STORE [[CST1]](s32), [[GEP1]](p0) :: (store 4 into %ir.ptr + 4) 1916; CHECK: [[CST8:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 1917; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST8]](s64) 1918; CHECK: G_STORE [[CST2]](s16), [[GEP2]](p0) :: (store 2 into %ir.ptr + 8, align 8) 1919; CHECK: [[CST9:%[0-9]+]]:_(s64) = G_CONSTANT i64 10 1920; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST9]](s64) 1921; CHECK: G_STORE [[CST3]](s8), [[GEP3]](p0) :: (store 1 into %ir.ptr + 10, align 2) 1922; CHECK: [[CST10:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 1923; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST10]](s64) 1924; CHECK: G_STORE [[CST4]](s64), [[GEP4]](p0) :: (store 8 into %ir.ptr + 16) 1925; CHECK: [[CST11:%[0-9]+]]:_(s64) = G_CONSTANT i64 24 1926; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST11]](s64) 1927; CHECK: G_STORE [[CST5]](s64), [[GEP5]](p0) :: (store 8 into %ir.ptr + 24) 1928; CHECK: [[CST12:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 1929; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST12]](s64) 1930; CHECK: G_STORE [[CST6]](s32), [[GEP6]](p0) :: (store 4 into %ir.ptr + 32, align 8) 1931 store %agg.nested { i32 1, i32 1, %agg.inner { i16 2, i8 3, %agg.inner.inner {i64 5, i64 8} }, i32 13}, %agg.nested *%ptr 1932 ret void 1933} 1934 1935define i1 @return_i1_zext() { 1936; AAPCS ABI says that booleans can only be 1 or 0, so we need to zero-extend. 1937; CHECK-LABEL: name: return_i1_zext 1938; CHECK: [[CST:%[0-9]+]]:_(s1) = G_CONSTANT i1 true 1939; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[CST]](s1) 1940; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8) 1941; CHECK: $w0 = COPY [[ANYEXT]](s32) 1942; CHECK: RET_ReallyLR implicit $w0 1943 ret i1 true 1944} 1945 1946; Try one cmpxchg 1947define i32 @test_atomic_cmpxchg_1(i32* %addr) { 1948; CHECK-LABEL: name: test_atomic_cmpxchg_1 1949; CHECK: bb.1.entry: 1950; CHECK-NEXT: successors: %bb.{{[^)]+}} 1951; CHECK-NEXT: liveins: $x0 1952; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1953; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 1954; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1955; CHECK: bb.2.repeat: 1956; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}}) 1957; CHECK: [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic 4 on %ir.addr) 1958; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3 1959; CHECK-NEXT: G_BR %bb.2 1960; CHECK: bb.3.done: 1961entry: 1962 br label %repeat 1963repeat: 1964 %val_success = cmpxchg i32* %addr, i32 0, i32 1 monotonic monotonic 1965 %value_loaded = extractvalue { i32, i1 } %val_success, 0 1966 %success = extractvalue { i32, i1 } %val_success, 1 1967 br i1 %success, label %done, label %repeat 1968done: 1969 ret i32 %value_loaded 1970} 1971 1972; Try one cmpxchg 1973define i32 @test_weak_atomic_cmpxchg_1(i32* %addr) { 1974; CHECK-LABEL: name: test_weak_atomic_cmpxchg_1 1975; CHECK: bb.1.entry: 1976; CHECK-NEXT: successors: %bb.{{[^)]+}} 1977; CHECK-NEXT: liveins: $x0 1978; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 1979; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 1980; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 1981; CHECK: bb.2.repeat: 1982; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}}) 1983; CHECK: [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic 4 on %ir.addr) 1984; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3 1985; CHECK-NEXT: G_BR %bb.2 1986; CHECK: bb.3.done: 1987entry: 1988 br label %repeat 1989repeat: 1990 %val_success = cmpxchg weak i32* %addr, i32 0, i32 1 monotonic monotonic 1991 %value_loaded = extractvalue { i32, i1 } %val_success, 0 1992 %success = extractvalue { i32, i1 } %val_success, 1 1993 br i1 %success, label %done, label %repeat 1994done: 1995 ret i32 %value_loaded 1996} 1997 1998; Try one cmpxchg with a small type and high atomic ordering. 1999define i16 @test_atomic_cmpxchg_2(i16* %addr) { 2000; CHECK-LABEL: name: test_atomic_cmpxchg_2 2001; CHECK: bb.1.entry: 2002; CHECK-NEXT: successors: %bb.2({{[^)]+}}) 2003; CHECK-NEXT: liveins: $x0 2004; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2005; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 0 2006; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 1 2007; CHECK: bb.2.repeat: 2008; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}}) 2009; CHECK: [[OLDVALRES:%[0-9]+]]:_(s16), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst seq_cst 2 on %ir.addr) 2010; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3 2011; CHECK-NEXT: G_BR %bb.2 2012; CHECK: bb.3.done: 2013entry: 2014 br label %repeat 2015repeat: 2016 %val_success = cmpxchg i16* %addr, i16 0, i16 1 seq_cst seq_cst 2017 %value_loaded = extractvalue { i16, i1 } %val_success, 0 2018 %success = extractvalue { i16, i1 } %val_success, 1 2019 br i1 %success, label %done, label %repeat 2020done: 2021 ret i16 %value_loaded 2022} 2023 2024; Try one cmpxchg where the success order and failure order differ. 2025define i64 @test_atomic_cmpxchg_3(i64* %addr) { 2026; CHECK-LABEL: name: test_atomic_cmpxchg_3 2027; CHECK: bb.1.entry: 2028; CHECK-NEXT: successors: %bb.2({{[^)]+}}) 2029; CHECK-NEXT: liveins: $x0 2030; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2031; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 2032; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 2033; CHECK: bb.2.repeat: 2034; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}}) 2035; CHECK: [[OLDVALRES:%[0-9]+]]:_(s64), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst acquire 8 on %ir.addr) 2036; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3 2037; CHECK-NEXT: G_BR %bb.2 2038; CHECK: bb.3.done: 2039entry: 2040 br label %repeat 2041repeat: 2042 %val_success = cmpxchg i64* %addr, i64 0, i64 1 seq_cst acquire 2043 %value_loaded = extractvalue { i64, i1 } %val_success, 0 2044 %success = extractvalue { i64, i1 } %val_success, 1 2045 br i1 %success, label %done, label %repeat 2046done: 2047 ret i64 %value_loaded 2048} 2049 2050; Try a monotonic atomicrmw xchg 2051; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2052define i32 @test_atomicrmw_xchg(i256* %addr) { 2053; CHECK-LABEL: name: test_atomicrmw_xchg 2054; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2055; CHECK-NEXT: liveins: $x0 2056; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2057; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2058; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XCHG [[ADDR]](p0), [[VAL]] :: (load store monotonic 32 on %ir.addr) 2059; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2060 %oldval = atomicrmw xchg i256* %addr, i256 1 monotonic 2061 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2062 ; test so work around it by truncating to i32 for now. 2063 %oldval.trunc = trunc i256 %oldval to i32 2064 ret i32 %oldval.trunc 2065} 2066 2067; Try an acquire atomicrmw add 2068; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2069define i32 @test_atomicrmw_add(i256* %addr) { 2070; CHECK-LABEL: name: test_atomicrmw_add 2071; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2072; CHECK-NEXT: liveins: $x0 2073; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2074; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2075; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_ADD [[ADDR]](p0), [[VAL]] :: (load store acquire 32 on %ir.addr) 2076; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2077 %oldval = atomicrmw add i256* %addr, i256 1 acquire 2078 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2079 ; test so work around it by truncating to i32 for now. 2080 %oldval.trunc = trunc i256 %oldval to i32 2081 ret i32 %oldval.trunc 2082} 2083 2084; Try a release atomicrmw sub 2085; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2086define i32 @test_atomicrmw_sub(i256* %addr) { 2087; CHECK-LABEL: name: test_atomicrmw_sub 2088; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2089; CHECK-NEXT: liveins: $x0 2090; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2091; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2092; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_SUB [[ADDR]](p0), [[VAL]] :: (load store release 32 on %ir.addr) 2093; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2094 %oldval = atomicrmw sub i256* %addr, i256 1 release 2095 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2096 ; test so work around it by truncating to i32 for now. 2097 %oldval.trunc = trunc i256 %oldval to i32 2098 ret i32 %oldval.trunc 2099} 2100 2101; Try an acq_rel atomicrmw and 2102; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2103define i32 @test_atomicrmw_and(i256* %addr) { 2104; CHECK-LABEL: name: test_atomicrmw_and 2105; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2106; CHECK-NEXT: liveins: $x0 2107; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2108; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2109; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_AND [[ADDR]](p0), [[VAL]] :: (load store acq_rel 32 on %ir.addr) 2110; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2111 %oldval = atomicrmw and i256* %addr, i256 1 acq_rel 2112 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2113 ; test so work around it by truncating to i32 for now. 2114 %oldval.trunc = trunc i256 %oldval to i32 2115 ret i32 %oldval.trunc 2116} 2117 2118; Try an seq_cst atomicrmw nand 2119; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2120define i32 @test_atomicrmw_nand(i256* %addr) { 2121; CHECK-LABEL: name: test_atomicrmw_nand 2122; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2123; CHECK-NEXT: liveins: $x0 2124; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2125; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2126; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_NAND [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2127; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2128 %oldval = atomicrmw nand i256* %addr, i256 1 seq_cst 2129 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2130 ; test so work around it by truncating to i32 for now. 2131 %oldval.trunc = trunc i256 %oldval to i32 2132 ret i32 %oldval.trunc 2133} 2134 2135; Try an seq_cst atomicrmw or 2136; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2137define i32 @test_atomicrmw_or(i256* %addr) { 2138; CHECK-LABEL: name: test_atomicrmw_or 2139; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2140; CHECK-NEXT: liveins: $x0 2141; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2142; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2143; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_OR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2144; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2145 %oldval = atomicrmw or i256* %addr, i256 1 seq_cst 2146 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2147 ; test so work around it by truncating to i32 for now. 2148 %oldval.trunc = trunc i256 %oldval to i32 2149 ret i32 %oldval.trunc 2150} 2151 2152; Try an seq_cst atomicrmw xor 2153; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2154define i32 @test_atomicrmw_xor(i256* %addr) { 2155; CHECK-LABEL: name: test_atomicrmw_xor 2156; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2157; CHECK-NEXT: liveins: $x0 2158; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2159; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2160; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XOR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2161; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2162 %oldval = atomicrmw xor i256* %addr, i256 1 seq_cst 2163 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2164 ; test so work around it by truncating to i32 for now. 2165 %oldval.trunc = trunc i256 %oldval to i32 2166 ret i32 %oldval.trunc 2167} 2168 2169; Try an seq_cst atomicrmw min 2170; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2171define i32 @test_atomicrmw_min(i256* %addr) { 2172; CHECK-LABEL: name: test_atomicrmw_min 2173; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2174; CHECK-NEXT: liveins: $x0 2175; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2176; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2177; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2178; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2179 %oldval = atomicrmw min i256* %addr, i256 1 seq_cst 2180 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2181 ; test so work around it by truncating to i32 for now. 2182 %oldval.trunc = trunc i256 %oldval to i32 2183 ret i32 %oldval.trunc 2184} 2185 2186; Try an seq_cst atomicrmw max 2187; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2188define i32 @test_atomicrmw_max(i256* %addr) { 2189; CHECK-LABEL: name: test_atomicrmw_max 2190; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2191; CHECK-NEXT: liveins: $x0 2192; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2193; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2194; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2195; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2196 %oldval = atomicrmw max i256* %addr, i256 1 seq_cst 2197 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2198 ; test so work around it by truncating to i32 for now. 2199 %oldval.trunc = trunc i256 %oldval to i32 2200 ret i32 %oldval.trunc 2201} 2202 2203; Try an seq_cst atomicrmw unsigned min 2204; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2205define i32 @test_atomicrmw_umin(i256* %addr) { 2206; CHECK-LABEL: name: test_atomicrmw_umin 2207; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2208; CHECK-NEXT: liveins: $x0 2209; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2210; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2211; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2212; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2213 %oldval = atomicrmw umin i256* %addr, i256 1 seq_cst 2214 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2215 ; test so work around it by truncating to i32 for now. 2216 %oldval.trunc = trunc i256 %oldval to i32 2217 ret i32 %oldval.trunc 2218} 2219 2220; Try an seq_cst atomicrmw unsigned max 2221; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this. 2222define i32 @test_atomicrmw_umax(i256* %addr) { 2223; CHECK-LABEL: name: test_atomicrmw_umax 2224; CHECK: bb.1 (%ir-block.{{[0-9]+}}): 2225; CHECK-NEXT: liveins: $x0 2226; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0 2227; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1 2228; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr) 2229; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]] 2230 %oldval = atomicrmw umax i256* %addr, i256 1 seq_cst 2231 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this 2232 ; test so work around it by truncating to i32 for now. 2233 %oldval.trunc = trunc i256 %oldval to i32 2234 ret i32 %oldval.trunc 2235} 2236 2237@addr = global i8* null 2238 2239define void @test_blockaddress() { 2240; CHECK-LABEL: name: test_blockaddress 2241; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block) 2242; CHECK: G_STORE [[BADDR]](p0) 2243 store i8* blockaddress(@test_blockaddress, %block), i8** @addr 2244 indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block] 2245block: 2246 ret void 2247} 2248 2249%t = type { i32 } 2250declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) readonly nounwind 2251declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind 2252define void @test_invariant_intrin() { 2253; CHECK-LABEL: name: test_invariant_intrin 2254; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF 2255; CHECK-NEXT: RET_ReallyLR 2256 %x = alloca %t 2257 %y = bitcast %t* %x to i8* 2258 %inv = call {}* @llvm.invariant.start.p0i8(i64 8, i8* %y) 2259 call void @llvm.invariant.end.p0i8({}* %inv, i64 8, i8* %y) 2260 ret void 2261} 2262 2263declare float @llvm.ceil.f32(float) 2264define float @test_ceil_f32(float %x) { 2265 ; CHECK-LABEL: name: test_ceil_f32 2266 ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}} 2267 %y = call float @llvm.ceil.f32(float %x) 2268 ret float %y 2269} 2270 2271declare double @llvm.ceil.f64(double) 2272define double @test_ceil_f64(double %x) { 2273 ; CHECK-LABEL: name: test_ceil_f64 2274 ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}} 2275 %y = call double @llvm.ceil.f64(double %x) 2276 ret double %y 2277} 2278 2279declare <2 x float> @llvm.ceil.v2f32(<2 x float>) 2280define <2 x float> @test_ceil_v2f32(<2 x float> %x) { 2281 ; CHECK-LABEL: name: test_ceil_v2f32 2282 ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}} 2283 %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x) 2284 ret <2 x float> %y 2285} 2286 2287declare <4 x float> @llvm.ceil.v4f32(<4 x float>) 2288define <4 x float> @test_ceil_v4f32(<4 x float> %x) { 2289 ; CHECK-LABEL: name: test_ceil_v4f32 2290 ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}} 2291 ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}} 2292 %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x) 2293 ret <4 x float> %y 2294} 2295 2296declare <2 x double> @llvm.ceil.v2f64(<2 x double>) 2297define <2 x double> @test_ceil_v2f64(<2 x double> %x) { 2298 ; CHECK-LABEL: name: test_ceil_v2f64 2299 ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}} 2300 %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x) 2301 ret <2 x double> %y 2302} 2303 2304declare float @llvm.cos.f32(float) 2305define float @test_cos_f32(float %x) { 2306 ; CHECK-LABEL: name: test_cos_f32 2307 ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOS %{{[0-9]+}} 2308 %y = call float @llvm.cos.f32(float %x) 2309 ret float %y 2310} 2311 2312declare float @llvm.sin.f32(float) 2313define float @test_sin_f32(float %x) { 2314 ; CHECK-LABEL: name: test_sin_f32 2315 ; CHECK: %{{[0-9]+}}:_(s32) = G_FSIN %{{[0-9]+}} 2316 %y = call float @llvm.sin.f32(float %x) 2317 ret float %y 2318} 2319 2320declare float @llvm.sqrt.f32(float) 2321define float @test_sqrt_f32(float %x) { 2322 ; CHECK-LABEL: name: test_sqrt_f32 2323 ; CHECK: %{{[0-9]+}}:_(s32) = G_FSQRT %{{[0-9]+}} 2324 %y = call float @llvm.sqrt.f32(float %x) 2325 ret float %y 2326} 2327 2328declare float @llvm.floor.f32(float) 2329define float @test_floor_f32(float %x) { 2330 ; CHECK-LABEL: name: test_floor_f32 2331 ; CHECK: %{{[0-9]+}}:_(s32) = G_FFLOOR %{{[0-9]+}} 2332 %y = call float @llvm.floor.f32(float %x) 2333 ret float %y 2334} 2335 2336declare float @llvm.nearbyint.f32(float) 2337define float @test_nearbyint_f32(float %x) { 2338 ; CHECK-LABEL: name: test_nearbyint_f32 2339 ; CHECK: %{{[0-9]+}}:_(s32) = G_FNEARBYINT %{{[0-9]+}} 2340 %y = call float @llvm.nearbyint.f32(float %x) 2341 ret float %y 2342} 2343 2344; CHECK-LABEL: name: test_llvm.aarch64.neon.ld3.v4i32.p0i32 2345; CHECK: %1:_(<4 x s32>), %2:_(<4 x s32>), %3:_(<4 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld3), %0(p0) :: (load 48 from %ir.ptr, align 64) 2346define void @test_llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr) { 2347 %arst = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr) 2348 ret void 2349} 2350 2351declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32*) #3 2352 2353define void @test_i1_arg_zext(void (i1)* %f) { 2354; CHECK-LABEL: name: test_i1_arg_zext 2355; CHECK: [[I1:%[0-9]+]]:_(s1) = G_CONSTANT i1 true 2356; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[I1]](s1) 2357; CHECK: $w0 = COPY [[ZEXT]](s32) 2358 call void %f(i1 true) 2359 ret void 2360} 2361 2362declare i8* @llvm.stacksave() 2363declare void @llvm.stackrestore(i8*) 2364define void @test_stacksaverestore() { 2365 ; CHECK-LABEL: name: test_stacksaverestore 2366 ; CHECK: [[SAVE:%[0-9]+]]:_(p0) = COPY $sp 2367 ; CHECK-NEXT: $sp = COPY [[SAVE]](p0) 2368 ; CHECK-NEXT: RET_ReallyLR 2369 %sp = call i8* @llvm.stacksave() 2370 call void @llvm.stackrestore(i8* %sp) 2371 ret void 2372} 2373 2374declare float @llvm.rint.f32(float) 2375define float @test_rint_f32(float %x) { 2376 ; CHECK-LABEL: name: test_rint_f32 2377 ; CHECK: %{{[0-9]+}}:_(s32) = G_FRINT %{{[0-9]+}} 2378 %y = call float @llvm.rint.f32(float %x) 2379 ret float %y 2380} 2381 2382declare void @llvm.assume(i1) 2383define void @test_assume(i1 %x) { 2384 ; CHECK-LABEL: name: test_assume 2385 ; CHECK-NOT: llvm.assume 2386 ; CHECK: RET_ReallyLR 2387 call void @llvm.assume(i1 %x) 2388 ret void 2389} 2390 2391declare void @llvm.sideeffect() 2392define void @test_sideeffect() { 2393 ; CHECK-LABEL: name: test_sideeffect 2394 ; CHECK-NOT: llvm.sideeffect 2395 ; CHECK: RET_ReallyLR 2396 call void @llvm.sideeffect() 2397 ret void 2398} 2399 2400declare void @llvm.var.annotation(i8*, i8*, i8*, i32, i8*) 2401define void @test_var_annotation(i8*, i8*, i8*, i32) { 2402 ; CHECK-LABEL: name: test_var_annotation 2403 ; CHECK-NOT: llvm.var.annotation 2404 ; CHECK: RET_ReallyLR 2405 call void @llvm.var.annotation(i8* %0, i8* %1, i8* %2, i32 %3, i8* null) 2406 ret void 2407} 2408 2409declare i64 @llvm.readcyclecounter() 2410define i64 @test_readcyclecounter() { 2411 ; CHECK-LABEL: name: test_readcyclecounter 2412 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_READCYCLECOUNTER{{$}} 2413 ; CHECK-NEXT: $x0 = COPY [[RES]] 2414 ; CHECK-NEXT: RET_ReallyLR implicit $x0 2415 %res = call i64 @llvm.readcyclecounter() 2416 ret i64 %res 2417} 2418 2419define i64 @test_freeze(i64 %a) { 2420 ; CHECK-LABEL: name: test_freeze 2421 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 2422 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]] 2423 ; CHECK-NEXT: $x0 = COPY [[RES]] 2424 ; CHECK-NEXT: RET_ReallyLR implicit $x0 2425 %res = freeze i64 %a 2426 ret i64 %res 2427} 2428 2429define {i8, i32} @test_freeze_struct({ i8, i32 }* %addr) { 2430 ; CHECK-LABEL: name: test_freeze_struct 2431 ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 2432 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) 2433 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 2434 ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]] 2435 ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) 2436 ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s8) = G_FREEZE [[LOAD]] 2437 ; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[LOAD1]] 2438 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[FREEZE]] 2439 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]] 2440 ; CHECK-NEXT: $w1 = COPY [[FREEZE1]] 2441 ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 2442 %load = load { i8, i32 }, { i8, i32 }* %addr 2443 %res = freeze {i8, i32} %load 2444 ret {i8, i32} %res 2445} 2446 2447!0 = !{ i64 0, i64 2 } 2448