brintos

brintos / llvm-project-archived public Read only

0
0
Text · 44.3 KiB · d48b070 Raw
1415 lines · plain
1; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-LE2; RUN: llc -mtriple=armebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-BE3; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE4; RUN: llc -mtriple=thumbebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE5 6@var8 = global i8 07@var16 = global i16 08@var32 = global i32 09@var64 = global i64 010 11define i8 @test_atomic_load_add_i8(i8 %offset) nounwind {12; CHECK-LABEL: test_atomic_load_add_i8:13   %old = atomicrmw add ptr @var8, i8 %offset seq_cst14; CHECK-NOT: dmb15; CHECK-NOT: mcr16; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var817; CHECK: movt r[[ADDR]], :upper16:var818 19; CHECK: .LBB{{[0-9]+}}_1:20; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]21  ; r0 below is a reasonable guess but could change: it certainly comes into the22  ;  function there.23; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r024; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]25; CHECK-NEXT: cmp [[STATUS]], #026; CHECK-NEXT: bne .LBB{{[0-9]+}}_127; CHECK-NOT: dmb28; CHECK-NOT: mcr29 30; CHECK: mov r0, r[[OLD]]31   ret i8 %old32}33 34define i16 @test_atomic_load_add_i16(i16 %offset) nounwind {35; CHECK-LABEL: test_atomic_load_add_i16:36   %old = atomicrmw add ptr @var16, i16 %offset acquire37; CHECK-NOT: dmb38; CHECK-NOT: mcr39; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var1640; CHECK: movt r[[ADDR]], :upper16:var1641 42; CHECK: .LBB{{[0-9]+}}_1:43; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]44  ; r0 below is a reasonable guess but could change: it certainly comes into the45  ;  function there.46; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r047; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]48; CHECK-NEXT: cmp [[STATUS]], #049; CHECK-NEXT: bne .LBB{{[0-9]+}}_150; CHECK-NOT: dmb51; CHECK-NOT: mcr52 53; CHECK: mov r0, r[[OLD]]54   ret i16 %old55}56 57define i32 @test_atomic_load_add_i32(i32 %offset) nounwind {58; CHECK-LABEL: test_atomic_load_add_i32:59   %old = atomicrmw add ptr @var32, i32 %offset release60; CHECK-NOT: dmb61; CHECK-NOT: mcr62; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var3263; CHECK: movt r[[ADDR]], :upper16:var3264 65; CHECK: .LBB{{[0-9]+}}_1:66; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]67  ; r0 below is a reasonable guess but could change: it certainly comes into the68  ;  function there.69; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r070; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]71; CHECK-NEXT: cmp [[STATUS]], #072; CHECK-NEXT: bne .LBB{{[0-9]+}}_173; CHECK-NOT: dmb74; CHECK-NOT: mcr75 76; CHECK: mov r0, r[[OLD]]77   ret i32 %old78}79 80define void @test_atomic_load_add_i64(i64 %offset) nounwind {81; CHECK-LABEL: test_atomic_load_add_i64:82   %old = atomicrmw add ptr @var64, i64 %offset monotonic83; CHECK-NOT: dmb84; CHECK-NOT: mcr85; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var6486; CHECK: movt r[[ADDR]], :upper16:var6487 88; CHECK: .LBB{{[0-9]+}}_1:89; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]90  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the91  ; function there.92; CHECK-LE-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r093; CHECK-LE-NEXT: adc{{(\.w)?}}  [[NEW2:r[0-9]+]], r[[OLD2]], r194; CHECK-BE-NEXT: adds{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r195; CHECK-BE-NEXT: adc{{(\.w)?}}  [[NEW1:r[0-9]+]], r[[OLD1]], r096; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]97; CHECK-NEXT: cmp [[STATUS]], #098; CHECK-NEXT: bne .LBB{{[0-9]+}}_199; CHECK-NOT: dmb100; CHECK-NOT: mcr101 102; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]103  store i64 %old, ptr @var64104   ret void105}106 107define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {108; CHECK-LABEL: test_atomic_load_sub_i8:109   %old = atomicrmw sub ptr @var8, i8 %offset monotonic110; CHECK-NOT: dmb111; CHECK-NOT: mcr112; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8113; CHECK: movt r[[ADDR]], :upper16:var8114 115; CHECK: .LBB{{[0-9]+}}_1:116; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]117  ; r0 below is a reasonable guess but could change: it certainly comes into the118  ;  function there.119; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0120; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]121; CHECK-NEXT: cmp [[STATUS]], #0122; CHECK-NEXT: bne .LBB{{[0-9]+}}_1123; CHECK-NOT: dmb124; CHECK-NOT: mcr125 126; CHECK: mov r0, r[[OLD]]127   ret i8 %old128}129 130define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {131; CHECK-LABEL: test_atomic_load_sub_i16:132   %old = atomicrmw sub ptr @var16, i16 %offset release133; CHECK-NOT: dmb134; CHECK-NOT: mcr135; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16136; CHECK: movt r[[ADDR]], :upper16:var16137 138; CHECK: .LBB{{[0-9]+}}_1:139; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]140  ; r0 below is a reasonable guess but could change: it certainly comes into the141  ;  function there.142; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0143; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]144; CHECK-NEXT: cmp [[STATUS]], #0145; CHECK-NEXT: bne .LBB{{[0-9]+}}_1146; CHECK-NOT: dmb147; CHECK-NOT: mcr148 149; CHECK: mov r0, r[[OLD]]150   ret i16 %old151}152 153define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {154; CHECK-LABEL: test_atomic_load_sub_i32:155   %old = atomicrmw sub ptr @var32, i32 %offset acquire156; CHECK-NOT: dmb157; CHECK-NOT: mcr158; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32159; CHECK: movt r[[ADDR]], :upper16:var32160 161; CHECK: .LBB{{[0-9]+}}_1:162; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]163  ; r0 below is a reasonable guess but could change: it certainly comes into the164  ;  function there.165; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0166; CHECK-NEXT: strex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]167; CHECK-NEXT: cmp [[STATUS]], #0168; CHECK-NEXT: bne .LBB{{[0-9]+}}_1169; CHECK-NOT: dmb170; CHECK-NOT: mcr171 172; CHECK: mov r0, r[[OLD]]173   ret i32 %old174}175 176define void @test_atomic_load_sub_i64(i64 %offset) nounwind {177; CHECK-LABEL: test_atomic_load_sub_i64:178   %old = atomicrmw sub ptr @var64, i64 %offset seq_cst179; CHECK-NOT: dmb180; CHECK-NOT: mcr181; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64182; CHECK: movt r[[ADDR]], :upper16:var64183 184; CHECK: .LBB{{[0-9]+}}_1:185; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]186  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the187  ; function there.188; CHECK-LE-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0189; CHECK-LE-NEXT: sbc{{(\.w)?}}  [[NEW2:r[0-9]+]], r[[OLD2]], r1190; CHECK-BE-NEXT: subs{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1191; CHECK-BE-NEXT: sbc{{(\.w)?}}  [[NEW1:r[0-9]+]], r[[OLD1]], r0192; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]193; CHECK-NEXT: cmp [[STATUS]], #0194; CHECK-NEXT: bne .LBB{{[0-9]+}}_1195; CHECK-NOT: dmb196; CHECK-NOT: mcr197 198; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]199   store i64 %old, ptr @var64200   ret void201}202 203define i8 @test_atomic_load_and_i8(i8 %offset) nounwind {204; CHECK-LABEL: test_atomic_load_and_i8:205   %old = atomicrmw and ptr @var8, i8 %offset release206; CHECK-NOT: dmb207; CHECK-NOT: mcr208; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8209; CHECK: movt r[[ADDR]], :upper16:var8210 211; CHECK: .LBB{{[0-9]+}}_1:212; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]213  ; r0 below is a reasonable guess but could change: it certainly comes into the214  ;  function there.215; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0216; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]217; CHECK-NEXT: cmp [[STATUS]], #0218; CHECK-NEXT: bne .LBB{{[0-9]+}}_1219; CHECK-NOT: dmb220; CHECK-NOT: mcr221 222; CHECK: mov r0, r[[OLD]]223   ret i8 %old224}225 226define i16 @test_atomic_load_and_i16(i16 %offset) nounwind {227; CHECK-LABEL: test_atomic_load_and_i16:228   %old = atomicrmw and ptr @var16, i16 %offset monotonic229; CHECK-NOT: dmb230; CHECK-NOT: mcr231; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16232; CHECK: movt r[[ADDR]], :upper16:var16233 234; CHECK: .LBB{{[0-9]+}}_1:235; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]236  ; r0 below is a reasonable guess but could change: it certainly comes into the237  ;  function there.238; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0239; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]240; CHECK-NEXT: cmp [[STATUS]], #0241; CHECK-NEXT: bne .LBB{{[0-9]+}}_1242; CHECK-NOT: dmb243; CHECK-NOT: mcr244 245; CHECK: mov r0, r[[OLD]]246   ret i16 %old247}248 249define i32 @test_atomic_load_and_i32(i32 %offset) nounwind {250; CHECK-LABEL: test_atomic_load_and_i32:251   %old = atomicrmw and ptr @var32, i32 %offset seq_cst252; CHECK-NOT: dmb253; CHECK-NOT: mcr254; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32255; CHECK: movt r[[ADDR]], :upper16:var32256 257; CHECK: .LBB{{[0-9]+}}_1:258; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]259  ; r0 below is a reasonable guess but could change: it certainly comes into the260  ;  function there.261; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0262; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]263; CHECK-NEXT: cmp [[STATUS]], #0264; CHECK-NEXT: bne .LBB{{[0-9]+}}_1265; CHECK-NOT: dmb266; CHECK-NOT: mcr267 268; CHECK: mov r0, r[[OLD]]269   ret i32 %old270}271 272define void @test_atomic_load_and_i64(i64 %offset) nounwind {273; CHECK-LABEL: test_atomic_load_and_i64:274   %old = atomicrmw and ptr @var64, i64 %offset acquire275; CHECK-NOT: dmb276; CHECK-NOT: mcr277; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64278; CHECK: movt r[[ADDR]], :upper16:var64279 280; CHECK: .LBB{{[0-9]+}}_1:281; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]282  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the283  ; function there.284; CHECK-LE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0285; CHECK-LE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1286; CHECK-BE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1287; CHECK-BE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0288; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]289; CHECK-NEXT: cmp [[STATUS]], #0290; CHECK-NEXT: bne .LBB{{[0-9]+}}_1291; CHECK-NOT: dmb292; CHECK-NOT: mcr293 294; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]295   store i64 %old, ptr @var64296   ret void297}298 299define i8 @test_atomic_load_or_i8(i8 %offset) nounwind {300; CHECK-LABEL: test_atomic_load_or_i8:301   %old = atomicrmw or ptr @var8, i8 %offset seq_cst302; CHECK-NOT: dmb303; CHECK-NOT: mcr304; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8305; CHECK: movt r[[ADDR]], :upper16:var8306 307; CHECK: .LBB{{[0-9]+}}_1:308; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]309  ; r0 below is a reasonable guess but could change: it certainly comes into the310  ;  function there.311; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0312; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]313; CHECK-NEXT: cmp [[STATUS]], #0314; CHECK-NEXT: bne .LBB{{[0-9]+}}_1315; CHECK-NOT: dmb316; CHECK-NOT: mcr317 318; CHECK: mov r0, r[[OLD]]319   ret i8 %old320}321 322define i16 @test_atomic_load_or_i16(i16 %offset) nounwind {323; CHECK-LABEL: test_atomic_load_or_i16:324   %old = atomicrmw or ptr @var16, i16 %offset monotonic325; CHECK-NOT: dmb326; CHECK-NOT: mcr327; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16328; CHECK: movt r[[ADDR]], :upper16:var16329 330; CHECK: .LBB{{[0-9]+}}_1:331; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]332  ; r0 below is a reasonable guess but could change: it certainly comes into the333  ;  function there.334; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0335; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]336; CHECK-NEXT: cmp [[STATUS]], #0337; CHECK-NEXT: bne .LBB{{[0-9]+}}_1338; CHECK-NOT: dmb339; CHECK-NOT: mcr340 341; CHECK: mov r0, r[[OLD]]342   ret i16 %old343}344 345define i32 @test_atomic_load_or_i32(i32 %offset) nounwind {346; CHECK-LABEL: test_atomic_load_or_i32:347   %old = atomicrmw or ptr @var32, i32 %offset acquire348; CHECK-NOT: dmb349; CHECK-NOT: mcr350; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32351; CHECK: movt r[[ADDR]], :upper16:var32352 353; CHECK: .LBB{{[0-9]+}}_1:354; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]355  ; r0 below is a reasonable guess but could change: it certainly comes into the356  ;  function there.357; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0358; CHECK-NEXT: strex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]359; CHECK-NEXT: cmp [[STATUS]], #0360; CHECK-NEXT: bne .LBB{{[0-9]+}}_1361; CHECK-NOT: dmb362; CHECK-NOT: mcr363 364; CHECK: mov r0, r[[OLD]]365   ret i32 %old366}367 368define void @test_atomic_load_or_i64(i64 %offset) nounwind {369; CHECK-LABEL: test_atomic_load_or_i64:370   %old = atomicrmw or ptr @var64, i64 %offset release371; CHECK-NOT: dmb372; CHECK-NOT: mcr373; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64374; CHECK: movt r[[ADDR]], :upper16:var64375 376; CHECK: .LBB{{[0-9]+}}_1:377; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]378  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the379  ; function there.380; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0381; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1382; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1383; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0384; CHECK: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]385; CHECK-NEXT: cmp [[STATUS]], #0386; CHECK-NEXT: bne .LBB{{[0-9]+}}_1387; CHECK-NOT: dmb388; CHECK-NOT: mcr389 390; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]391   store i64 %old, ptr @var64392   ret void393}394 395define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {396; CHECK-LABEL: test_atomic_load_xor_i8:397   %old = atomicrmw xor ptr @var8, i8 %offset acquire398; CHECK-NOT: dmb399; CHECK-NOT: mcr400; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8401; CHECK: movt r[[ADDR]], :upper16:var8402 403; CHECK: .LBB{{[0-9]+}}_1:404; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]405  ; r0 below is a reasonable guess but could change: it certainly comes into the406  ;  function there.407; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0408; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]409; CHECK-NEXT: cmp [[STATUS]], #0410; CHECK-NEXT: bne .LBB{{[0-9]+}}_1411; CHECK-NOT: dmb412; CHECK-NOT: mcr413 414; CHECK: mov r0, r[[OLD]]415   ret i8 %old416}417 418define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {419; CHECK-LABEL: test_atomic_load_xor_i16:420   %old = atomicrmw xor ptr @var16, i16 %offset release421; CHECK-NOT: dmb422; CHECK-NOT: mcr423; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16424; CHECK: movt r[[ADDR]], :upper16:var16425 426; CHECK: .LBB{{[0-9]+}}_1:427; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]428  ; r0 below is a reasonable guess but could change: it certainly comes into the429  ;  function there.430; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0431; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]432; CHECK-NEXT: cmp [[STATUS]], #0433; CHECK-NEXT: bne .LBB{{[0-9]+}}_1434; CHECK-NOT: dmb435; CHECK-NOT: mcr436 437; CHECK: mov r0, r[[OLD]]438   ret i16 %old439}440 441define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {442; CHECK-LABEL: test_atomic_load_xor_i32:443   %old = atomicrmw xor ptr @var32, i32 %offset seq_cst444; CHECK-NOT: dmb445; CHECK-NOT: mcr446; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32447; CHECK: movt r[[ADDR]], :upper16:var32448 449; CHECK: .LBB{{[0-9]+}}_1:450; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]451  ; r0 below is a reasonable guess but could change: it certainly comes into the452  ;  function there.453; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0454; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]455; CHECK-NEXT: cmp [[STATUS]], #0456; CHECK-NEXT: bne .LBB{{[0-9]+}}_1457; CHECK-NOT: dmb458; CHECK-NOT: mcr459 460; CHECK: mov r0, r[[OLD]]461   ret i32 %old462}463 464define void @test_atomic_load_xor_i64(i64 %offset) nounwind {465; CHECK-LABEL: test_atomic_load_xor_i64:466   %old = atomicrmw xor ptr @var64, i64 %offset monotonic467; CHECK-NOT: dmb468; CHECK-NOT: mcr469; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64470; CHECK: movt r[[ADDR]], :upper16:var64471 472; CHECK: .LBB{{[0-9]+}}_1:473; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]474  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the475  ; function there.476; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0477; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1478; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1479; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0480; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]481; CHECK-NEXT: cmp [[STATUS]], #0482; CHECK-NEXT: bne .LBB{{[0-9]+}}_1483; CHECK-NOT: dmb484; CHECK-NOT: mcr485 486; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]487   store i64 %old, ptr @var64488   ret void489}490 491define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {492; CHECK-LABEL: test_atomic_load_xchg_i8:493   %old = atomicrmw xchg ptr @var8, i8 %offset monotonic494; CHECK-NOT: dmb495; CHECK-NOT: mcr496; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8497; CHECK: movt r[[ADDR]], :upper16:var8498 499; CHECK: .LBB{{[0-9]+}}_1:500; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]501  ; r0 below is a reasonable guess but could change: it certainly comes into the502  ;  function there.503; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]504; CHECK-NEXT: cmp [[STATUS]], #0505; CHECK-NEXT: bne .LBB{{[0-9]+}}_1506; CHECK-NOT: dmb507; CHECK-NOT: mcr508 509; CHECK: mov r0, r[[OLD]]510   ret i8 %old511}512 513define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {514; CHECK-LABEL: test_atomic_load_xchg_i16:515   %old = atomicrmw xchg ptr @var16, i16 %offset seq_cst516; CHECK-NOT: dmb517; CHECK-NOT: mcr518; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16519; CHECK: movt r[[ADDR]], :upper16:var16520 521; CHECK: .LBB{{[0-9]+}}_1:522; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]523  ; r0 below is a reasonable guess but could change: it certainly comes into the524  ;  function there.525; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]526; CHECK-NEXT: cmp [[STATUS]], #0527; CHECK-NEXT: bne .LBB{{[0-9]+}}_1528; CHECK-NOT: dmb529; CHECK-NOT: mcr530 531; CHECK: mov r0, r[[OLD]]532   ret i16 %old533}534 535define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {536; CHECK-LABEL: test_atomic_load_xchg_i32:537   %old = atomicrmw xchg ptr @var32, i32 %offset release538; CHECK-NOT: dmb539; CHECK-NOT: mcr540; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32541; CHECK: movt r[[ADDR]], :upper16:var32542 543; CHECK: .LBB{{[0-9]+}}_1:544; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]545  ; r0 below is a reasonable guess but could change: it certainly comes into the546  ;  function there.547; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]548; CHECK-NEXT: cmp [[STATUS]], #0549; CHECK-NEXT: bne .LBB{{[0-9]+}}_1550; CHECK-NOT: dmb551; CHECK-NOT: mcr552 553; CHECK: mov r0, r[[OLD]]554   ret i32 %old555}556 557define void @test_atomic_load_xchg_i64(i64 %offset) nounwind {558; CHECK-LABEL: test_atomic_load_xchg_i64:559   %old = atomicrmw xchg ptr @var64, i64 %offset acquire560; CHECK-NOT: dmb561; CHECK-NOT: mcr562; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64563; CHECK: movt r[[ADDR]], :upper16:var64564 565; CHECK: .LBB{{[0-9]+}}_1:566; CHECK: ldaexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]567  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the568  ; function there.569; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]]570; CHECK-NEXT: cmp [[STATUS]], #0571; CHECK-NEXT: bne .LBB{{[0-9]+}}_1572; CHECK-NOT: dmb573; CHECK-NOT: mcr574 575; CHECK: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]576   store i64 %old, ptr @var64577   ret void578}579 580define i8 @test_atomic_load_min_i8(i8 signext %offset) nounwind {581; CHECK-LABEL: test_atomic_load_min_i8:582   %old = atomicrmw min ptr @var8, i8 %offset acquire583; CHECK-NOT: dmb584; CHECK-NOT: mcr585; CHECK-DAG: movw [[ADDR:r[0-9]+|lr]], :lower16:var8586; CHECK-DAG: movt [[ADDR]], :upper16:var8587 588; CHECK: .LBB{{[0-9]+}}_1:589; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]590; CHECK-NEXT: sxtb r[[OLDX:[0-9]+]], r[[OLD]]591  ; r0 below is a reasonable guess but could change: it certainly comes into the592  ;  function there.593; CHECK-NEXT: cmp r[[OLDX]], r0594; Thumb mode: it le595; CHECK:      movle r[[OLDX]], r[[OLD]]596; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]]597; CHECK-NEXT: cmp [[STATUS]], #0598; CHECK-NEXT: bne .LBB{{[0-9]+}}_1599; CHECK-NOT: dmb600; CHECK-NOT: mcr601 602; CHECK: mov r0, r[[OLD]]603   ret i8 %old604}605 606define i16 @test_atomic_load_min_i16(i16 signext %offset) nounwind {607; CHECK-LABEL: test_atomic_load_min_i16:608   %old = atomicrmw min ptr @var16, i16 %offset release609; CHECK-NOT: dmb610; CHECK-NOT: mcr611; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16612; CHECK: movt [[ADDR]], :upper16:var16613 614; CHECK: .LBB{{[0-9]+}}_1:615; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]616; CHECK-NEXT: sxth r[[OLDX:[0-9]+]], r[[OLD]]617  ; r0 below is a reasonable guess but could change: it certainly comes into the618  ;  function there.619; CHECK-NEXT: cmp r[[OLDX]], r0620; Thumb mode: it le621; CHECK:      movle r[[OLDX]], r[[OLD]]622; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]623; CHECK-NEXT: cmp [[STATUS]], #0624; CHECK-NEXT: bne .LBB{{[0-9]+}}_1625; CHECK-NOT: dmb626; CHECK-NOT: mcr627 628; CHECK: mov r0, r[[OLD]]629   ret i16 %old630}631 632define i32 @test_atomic_load_min_i32(i32 %offset) nounwind {633; CHECK-LABEL: test_atomic_load_min_i32:634   %old = atomicrmw min ptr @var32, i32 %offset monotonic635; CHECK-NOT: dmb636; CHECK-NOT: mcr637; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32638; CHECK: movt r[[ADDR]], :upper16:var32639 640; CHECK: .LBB{{[0-9]+}}_1:641; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]642  ; r0 below is a reasonable guess but could change: it certainly comes into the643  ;  function there.644; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0645; CHECK-NEXT: cmp r[[OLD]], r0646; Thumb mode: it le647; CHECK:      movle r[[NEW]], r[[OLD]]648; CHECK-NEXT: strex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]649; CHECK-NEXT: cmp [[STATUS]], #0650; CHECK-NEXT: bne .LBB{{[0-9]+}}_1651; CHECK-NOT: dmb652; CHECK-NOT: mcr653 654; CHECK: mov r0, r[[OLD]]655   ret i32 %old656}657 658define void @test_atomic_load_min_i64(i64 %offset) nounwind {659; CHECK-LABEL: test_atomic_load_min_i64:660   %old = atomicrmw min ptr @var64, i64 %offset seq_cst661; CHECK-NOT: dmb662; CHECK-NOT: mcr663; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64664; CHECK: movt r[[ADDR]], :upper16:var64665 666; CHECK: .LBB{{[0-9]+}}_1:667; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]668  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the669  ; function there.670; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1671; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]672; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]673; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]674; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]675; CHECK-ARM: movge [[MINHI]], [[OLD2]]676; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0677; CHECK-ARM: movge [[MINLO]], [[OLD1]]678; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]679; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]680; CHECK-NEXT: cmp [[STATUS]], #0681; CHECK-NEXT: bne .LBB{{[0-9]+}}_1682; CHECK-NOT: dmb683; CHECK-NOT: mcr684 685; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]686   store i64 %old, ptr @var64687   ret void688}689 690define i8 @test_atomic_load_max_i8(i8 signext %offset) nounwind {691; CHECK-LABEL: test_atomic_load_max_i8:692   %old = atomicrmw max ptr @var8, i8 %offset seq_cst693; CHECK-NOT: dmb694; CHECK-NOT: mcr695; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8696; CHECK: movt [[ADDR]], :upper16:var8697 698; CHECK: .LBB{{[0-9]+}}_1:699; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]700; CHECK-NEXT: sxtb r[[OLDX:[0-9]+]], r[[OLD]]701  ; r0 below is a reasonable guess but could change: it certainly comes into the702  ;  function there.703; CHECK-NEXT: cmp r[[OLDX]], r0704; Thumb mode: it gt705; CHECK:      movgt r[[OLDX]], r[[OLD]]706; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]707; CHECK-NEXT: cmp [[STATUS]], #0708; CHECK-NEXT: bne .LBB{{[0-9]+}}_1709; CHECK-NOT: dmb710; CHECK-NOT: mcr711 712; CHECK: mov r0, r[[OLD]]713   ret i8 %old714}715 716define i16 @test_atomic_load_max_i16(i16 signext %offset) nounwind {717; CHECK-LABEL: test_atomic_load_max_i16:718   %old = atomicrmw max ptr @var16, i16 %offset acquire719; CHECK-NOT: dmb720; CHECK-NOT: mcr721; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16722; CHECK: movt r[[ADDR]], :upper16:var16723 724; CHECK: .LBB{{[0-9]+}}_1:725; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]726; CHECK-NEXT: sxth r[[OLDX:[0-9]+]], r[[OLD]]727  ; r0 below is a reasonable guess but could change: it certainly comes into the728  ;  function there.729; CHECK-NEXT: cmp r[[OLDX]], r0730; Thumb mode: it gt731; CHECK:      movgt r[[OLDX]], r[[OLD]]732; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[OLDX]], [r[[ADDR]]]733; CHECK-NEXT: cmp [[STATUS]], #0734; CHECK-NEXT: bne .LBB{{[0-9]+}}_1735; CHECK-NOT: dmb736; CHECK-NOT: mcr737 738; CHECK: mov r0, r[[OLD]]739   ret i16 %old740}741 742define i32 @test_atomic_load_max_i32(i32 %offset) nounwind {743; CHECK-LABEL: test_atomic_load_max_i32:744   %old = atomicrmw max ptr @var32, i32 %offset release745; CHECK-NOT: dmb746; CHECK-NOT: mcr747; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32748; CHECK: movt r[[ADDR]], :upper16:var32749 750; CHECK: .LBB{{[0-9]+}}_1:751; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]752  ; r0 below is a reasonable guess but could change: it certainly comes into the753  ;  function there.754; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0755; CHECK-NEXT: cmp r[[OLD]], r0756; Thumb mode: it gt757; CHECK:      movgt r[[NEW]], r[[OLD]]758; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]759; CHECK-NEXT: cmp [[STATUS]], #0760; CHECK-NEXT: bne .LBB{{[0-9]+}}_1761; CHECK-NOT: dmb762; CHECK-NOT: mcr763 764; CHECK: mov r0, r[[OLD]]765   ret i32 %old766}767 768define void @test_atomic_load_max_i64(i64 %offset) nounwind {769; CHECK-LABEL: test_atomic_load_max_i64:770   %old = atomicrmw max ptr @var64, i64 %offset monotonic771; CHECK-NOT: dmb772; CHECK-NOT: mcr773; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64774; CHECK: movt r[[ADDR]], :upper16:var64775 776; CHECK: .LBB{{[0-9]+}}_1:777; CHECK: ldrexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]778  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the779  ; function there.780; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1781; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]782; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]783; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]784; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]785; CHECK-ARM: movlt [[MINHI]], [[OLD2]]786; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0787; CHECK-ARM: movlt [[MINLO]], [[OLD1]]788; CHECK-ARM: strexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]789; CHECK-THUMB: strexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]790; CHECK-NEXT: cmp [[STATUS]], #0791; CHECK-NEXT: bne .LBB{{[0-9]+}}_1792; CHECK-NOT: dmb793; CHECK-NOT: mcr794 795; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]796   store i64 %old, ptr @var64797   ret void798}799 800define i8 @test_atomic_load_umin_i8(i8 zeroext %offset) nounwind {801; CHECK-LABEL: test_atomic_load_umin_i8:802   %old = atomicrmw umin ptr @var8, i8 %offset monotonic803; CHECK-NOT: dmb804; CHECK-NOT: mcr805; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8806; CHECK: movt [[ADDR]], :upper16:var8807 808; CHECK: .LBB{{[0-9]+}}_1:809; CHECK: ldrexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]810  ; r0 below is a reasonable guess but could change: it certainly comes into the811  ;  function there.812; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0813; CHECK-NEXT: cmp r[[OLD]], r0814; Thumb mode: it ls815; CHECK:      movls r[[NEW]], r[[OLD]]816; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]817; CHECK-NEXT: cmp [[STATUS]], #0818; CHECK-NEXT: bne .LBB{{[0-9]+}}_1819; CHECK-NOT: dmb820; CHECK-NOT: mcr821 822; CHECK: mov r0, r[[OLD]]823   ret i8 %old824}825 826define i16 @test_atomic_load_umin_i16(i16 zeroext %offset) nounwind {827; CHECK-LABEL: test_atomic_load_umin_i16:828   %old = atomicrmw umin ptr @var16, i16 %offset acquire829; CHECK-NOT: dmb830; CHECK-NOT: mcr831; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16832; CHECK: movt [[ADDR]], :upper16:var16833 834; CHECK: .LBB{{[0-9]+}}_1:835; CHECK: ldaexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]836  ; r0 below is a reasonable guess but could change: it certainly comes into the837  ;  function there.838; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0839; CHECK-NEXT: cmp r[[OLD]], r0840; Thumb mode: it ls841; CHECK:      movls r[[NEW]], r[[OLD]]842; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]843; CHECK-NEXT: cmp [[STATUS]], #0844; CHECK-NEXT: bne .LBB{{[0-9]+}}_1845; CHECK-NOT: dmb846; CHECK-NOT: mcr847 848; CHECK: mov r0, r[[OLD]]849   ret i16 %old850}851 852define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {853; CHECK-LABEL: test_atomic_load_umin_i32:854   %old = atomicrmw umin ptr @var32, i32 %offset seq_cst855; CHECK-NOT: dmb856; CHECK-NOT: mcr857; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32858; CHECK: movt r[[ADDR]], :upper16:var32859 860; CHECK: .LBB{{[0-9]+}}_1:861; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]862  ; r0 below is a reasonable guess but could change: it certainly comes into the863  ;  function there.864; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0865; CHECK-NEXT: cmp r[[OLD]], r0866; Thumb mode: it ls867; CHECK:      movls r[[NEW]], r[[OLD]]868; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]869; CHECK-NEXT: cmp [[STATUS]], #0870; CHECK-NEXT: bne .LBB{{[0-9]+}}_1871; CHECK-NOT: dmb872; CHECK-NOT: mcr873 874; CHECK: mov r0, r[[OLD]]875   ret i32 %old876}877 878define void @test_atomic_load_umin_i64(i64 %offset) nounwind {879; CHECK-LABEL: test_atomic_load_umin_i64:880   %old = atomicrmw umin ptr @var64, i64 %offset seq_cst881; CHECK-NOT: dmb882; CHECK-NOT: mcr883; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64884; CHECK: movt r[[ADDR]], :upper16:var64885 886; CHECK: .LBB{{[0-9]+}}_1:887; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]888  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the889  ; function there.890; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1891; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]892; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]893; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]894; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]895; CHECK-ARM: movhs [[MINHI]], [[OLD2]]896; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0897; CHECK-ARM: movhs [[MINLO]], [[OLD1]]898; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]899; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]900; CHECK-NEXT: cmp [[STATUS]], #0901; CHECK-NEXT: bne .LBB{{[0-9]+}}_1902; CHECK-NOT: dmb903; CHECK-NOT: mcr904 905; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]906   store i64 %old, ptr @var64907   ret void908}909 910define i8 @test_atomic_load_umax_i8(i8 zeroext %offset) nounwind {911; CHECK-LABEL: test_atomic_load_umax_i8:912   %old = atomicrmw umax ptr @var8, i8 %offset acq_rel913; CHECK-NOT: dmb914; CHECK-NOT: mcr915; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8916; CHECK: movt [[ADDR]], :upper16:var8917 918; CHECK: .LBB{{[0-9]+}}_1:919; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]920  ; r0 below is a reasonable guess but could change: it certainly comes into the921  ;  function there.922; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0923; CHECK-NEXT: cmp r[[OLD]], r0924; Thumb mode: it hi925; CHECK:      movhi r[[NEW]], r[[OLD]]926; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]927; CHECK-NEXT: cmp [[STATUS]], #0928; CHECK-NEXT: bne .LBB{{[0-9]+}}_1929; CHECK-NOT: dmb930; CHECK-NOT: mcr931 932; CHECK: mov r0, r[[OLD]]933   ret i8 %old934}935 936define i16 @test_atomic_load_umax_i16(i16 zeroext %offset) nounwind {937; CHECK-LABEL: test_atomic_load_umax_i16:938   %old = atomicrmw umax ptr @var16, i16 %offset monotonic939; CHECK-NOT: dmb940; CHECK-NOT: mcr941; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16942; CHECK: movt [[ADDR]], :upper16:var16943 944; CHECK: .LBB{{[0-9]+}}_1:945; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]946  ; r0 below is a reasonable guess but could change: it certainly comes into the947  ;  function there.948; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0949; CHECK-NEXT: cmp r[[OLD]], r0950; Thumb mode: it hi951; CHECK:      movhi r[[NEW]], r[[OLD]]952; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]953; CHECK-NEXT: cmp [[STATUS]], #0954; CHECK-NEXT: bne .LBB{{[0-9]+}}_1955; CHECK-NOT: dmb956; CHECK-NOT: mcr957 958; CHECK: mov r0, r[[OLD]]959   ret i16 %old960}961 962define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {963; CHECK-LABEL: test_atomic_load_umax_i32:964   %old = atomicrmw umax ptr @var32, i32 %offset seq_cst965; CHECK-NOT: dmb966; CHECK-NOT: mcr967; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32968; CHECK: movt r[[ADDR]], :upper16:var32969 970; CHECK: .LBB{{[0-9]+}}_1:971; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]972  ; r0 below is a reasonable guess but could change: it certainly comes into the973  ;  function there.974; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0975; CHECK-NEXT: cmp r[[OLD]], r0976; Thumb mode: it hi977; CHECK:      movhi r[[NEW]], r[[OLD]]978; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]979; CHECK-NEXT: cmp [[STATUS]], #0980; CHECK-NEXT: bne .LBB{{[0-9]+}}_1981; CHECK-NOT: dmb982; CHECK-NOT: mcr983 984; CHECK: mov r0, r[[OLD]]985   ret i32 %old986}987 988define void @test_atomic_load_umax_i64(i64 %offset) nounwind {989; CHECK-LABEL: test_atomic_load_umax_i64:990   %old = atomicrmw umax ptr @var64, i64 %offset seq_cst991; CHECK-NOT: dmb992; CHECK-NOT: mcr993; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64994; CHECK: movt r[[ADDR]], :upper16:var64995 996; CHECK: .LBB{{[0-9]+}}_1:997; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]998  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the999  ; function there.1000; CHECK-ARM: mov [[MINHI:r[0-9]+]], r11001; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]1002; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]1003; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]1004; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]1005; CHECK-ARM: movlo [[MINHI]], [[OLD2]]1006; CHECK-ARM: mov [[MINLO:r[0-9]+]], r01007; CHECK-ARM: movlo [[MINLO]], [[OLD1]]1008; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]1009; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]1010; CHECK-NEXT: cmp [[STATUS]], #01011; CHECK-NEXT: bne .LBB{{[0-9]+}}_11012; CHECK-NOT: dmb1013; CHECK-NOT: mcr1014 1015; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]1016   store i64 %old, ptr @var641017   ret void1018}1019 1020define i8 @test_atomic_cmpxchg_i8(i8 zeroext %wanted, i8 zeroext %new) nounwind {1021; CHECK-LABEL: test_atomic_cmpxchg_i8:1022   %pair = cmpxchg ptr @var8, i8 %wanted, i8 %new acquire acquire1023   %old = extractvalue { i8, i1 } %pair, 01024; CHECK-NOT: dmb1025; CHECK-NOT: mcr1026; CHECK-DAG: movw r[[ADDR:[0-9]+]], :lower16:var81027; CHECK-DAG: movt r[[ADDR]], :upper16:var81028; CHECK-THUMB-DAG: mov r[[WANTED:[0-9]+]], r01029 1030; CHECK: .LBB{{[0-9]+}}_1:1031; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]1032  ; r0 below is a reasonable guess but could change: it certainly comes into the1033  ;  function there.1034; CHECK-ARM-NEXT:   cmp r[[OLD]], r01035; CHECK-THUMB-NEXT: cmp r[[OLD]], r[[WANTED]]1036; CHECK-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}1037; CHECK-NEXT: %bb.2:1038  ; As above, r1 is a reasonable guess.1039; CHECK: strexb [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]1040; CHECK-NEXT: cmp [[STATUS]], #01041; CHECK-ARM-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}1042; CHECK-THUMB-NEXT: it eq1043; CHECK-THUMB-NEXT: bxeq lr1044; CHECK-ARM: mov r0, r[[OLD]]1045; CHECK-ARM: clrex1046; CHECK: bx lr1047; CHECK-NOT: dmb1048; CHECK-NOT: mcr1049   ret i8 %old1050}1051 1052define i16 @test_atomic_cmpxchg_i16(i16 zeroext %wanted, i16 zeroext %new) nounwind {1053; CHECK-LABEL: test_atomic_cmpxchg_i16:1054   %pair = cmpxchg ptr @var16, i16 %wanted, i16 %new seq_cst seq_cst1055   %old = extractvalue { i16, i1 } %pair, 01056; CHECK-NOT: dmb1057; CHECK-NOT: mcr1058; CHECK-DAG: movw r[[ADDR:[0-9]+]], :lower16:var161059; CHECK-DAG: movt r[[ADDR]], :upper16:var161060; CHECK-THUMB-DAG: mov r[[WANTED:[0-9]+]], r01061 1062; CHECK: .LBB{{[0-9]+}}_1:1063; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]1064  ; r0 below is a reasonable guess but could change: it certainly comes into the1065  ;  function there.1066; CHECK-ARM-NEXT:   cmp r[[OLD]], r01067; CHECK-THUMB-NEXT: cmp r[[OLD]], r[[WANTED]]1068; CHECK-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}1069; CHECK-NEXT: %bb.2:1070  ; As above, r1 is a reasonable guess.1071; CHECK: stlexh [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]1072; CHECK-NEXT: cmp [[STATUS]], #01073; CHECK-ARM-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}1074; CHECK-THUMB-NEXT: it eq1075; CHECK-THUMB-NEXT: bxeq lr1076; CHECK-ARM: mov r0, r[[OLD]]1077; CHECK: bx lr1078; CHECK-ARM-NEXT: .LBB{{[0-9]+}}_{{[0-9]}}1079; CHECK-ARM-NEXT: clrex1080; CHECK-NOT: dmb1081; CHECK-NOT: mcr1082 1083; CHECK-ARM: mov r0, r[[OLD]]1084; CHECK-ARM-NEXT: bx lr1085   ret i16 %old1086}1087 1088define void @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {1089; CHECK-LABEL: test_atomic_cmpxchg_i32:1090   %pair = cmpxchg ptr @var32, i32 %wanted, i32 %new release monotonic1091   %old = extractvalue { i32, i1 } %pair, 01092   store i32 %old, ptr @var321093; CHECK-NOT: dmb1094; CHECK-NOT: mcr1095; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var321096; CHECK: movt r[[ADDR]], :upper16:var321097 1098; CHECK: .LBB{{[0-9]+}}_1:1099; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]1100  ; r0 below is a reasonable guess but could change: it certainly comes into the1101  ;  function there.1102; CHECK-NEXT: cmp r[[OLD]], r01103; CHECK-NEXT: bne .LBB{{[0-9]+}}_41104; CHECK-NEXT: %bb.2:1105  ; As above, r1 is a reasonable guess.1106; CHECK: stlex [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]1107; CHECK-NEXT: cmp [[STATUS]], #01108; CHECK-NEXT: bne .LBB{{[0-9]+}}_11109; CHECK: str{{(.w)?}} r[[OLD]],1110; CHECK-NEXT: bx lr1111; CHECK-NEXT: .LBB{{[0-9]+}}_4:1112; CHECK-NEXT: clrex1113; CHECK-NOT: dmb1114; CHECK-NOT: mcr1115 1116; CHECK: str{{(.w)?}} r[[OLD]],1117; CHECK-ARM-NEXT: bx lr1118   ret void1119}1120 1121define void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {1122; CHECK-LABEL: test_atomic_cmpxchg_i64:1123   %pair = cmpxchg ptr @var64, i64 %wanted, i64 %new monotonic monotonic1124   %old = extractvalue { i64, i1 } %pair, 01125; CHECK-NOT: dmb1126; CHECK-NOT: mcr1127; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var641128; CHECK: movt r[[ADDR]], :upper16:var641129 1130; CHECK: .LBB{{[0-9]+}}_1:1131; CHECK: ldrexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]1132  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the1133  ; function there.1134; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r01135; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r11136; CHECK-ARM-LE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]1137; CHECK-THUMB-LE: orrs{{(\.w)?}} {{(r[0-9]+, )?}}[[MISMATCH_HI]], [[MISMATCH_LO]]1138; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r11139; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r01140; CHECK-ARM-BE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_HI]], [[MISMATCH_LO]]1141; CHECK-THUMB-BE: orrs{{(\.w)?}} {{(r[0-9]+, )?}}[[MISMATCH_LO]], [[MISMATCH_HI]]1142; CHECK-NEXT: bne .LBB{{[0-9]+}}_41143; CHECK-NEXT: %bb.2:1144  ; As above, r2, r3 is a reasonable guess.1145; CHECK: strexd [[STATUS:r[0-9]+]], r2, r3, [r[[ADDR]]]1146; CHECK-NEXT: cmp [[STATUS]], #01147; CHECK-NEXT: bne .LBB{{[0-9]+}}_11148; CHECK: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]1149; CHECK-NEXT: pop1150; CHECK-NEXT: .LBB{{[0-9]+}}_4:1151; CHECK-NEXT: clrex1152; CHECK-NOT: dmb1153; CHECK-NOT: mcr1154 1155; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]1156   store i64 %old, ptr @var641157   ret void1158}1159 1160define i8 @test_atomic_load_monotonic_i8() nounwind {1161; CHECK-LABEL: test_atomic_load_monotonic_i8:1162  %val = load atomic i8, ptr @var8 monotonic, align 11163; CHECK-NOT: dmb1164; CHECK-NOT: mcr1165; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var81166; CHECK: movt r[[ADDR]], :upper16:var81167; CHECK: ldrb r0, [r[[ADDR]]]1168; CHECK-NOT: dmb1169; CHECK-NOT: mcr1170 1171  ret i8 %val1172}1173 1174define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {1175; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:1176  %addr_int = add i64 %base, %off1177  %addr = inttoptr i64 %addr_int to ptr1178 1179  %val = load atomic i8, ptr %addr monotonic, align 11180; CHECK-NOT: dmb1181; CHECK-NOT: mcr1182; CHECK-LE: ldrb r0, [r0, r2]1183; CHECK-BE: ldrb r0, [r1, r3]1184; CHECK-NOT: dmb1185; CHECK-NOT: mcr1186 1187  ret i8 %val1188}1189 1190define i8 @test_atomic_load_acquire_i8() nounwind {1191; CHECK-LABEL: test_atomic_load_acquire_i8:1192  %val = load atomic i8, ptr @var8 acquire, align 11193; CHECK-NOT: dmb1194; CHECK-NOT: mcr1195; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var81196; CHECK-NOT: dmb1197; CHECK-NOT: mcr1198; CHECK: movt r[[ADDR]], :upper16:var81199; CHECK-NOT: dmb1200; CHECK-NOT: mcr1201; CHECK: ldab r0, [r[[ADDR]]]1202; CHECK-NOT: dmb1203; CHECK-NOT: mcr1204  ret i8 %val1205}1206 1207define i8 @test_atomic_load_seq_cst_i8() nounwind {1208; CHECK-LABEL: test_atomic_load_seq_cst_i8:1209  %val = load atomic i8, ptr @var8 seq_cst, align 11210; CHECK-NOT: dmb1211; CHECK-NOT: mcr1212; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var81213; CHECK-NOT: dmb1214; CHECK-NOT: mcr1215; CHECK: movt r[[ADDR]], :upper16:var81216; CHECK-NOT: dmb1217; CHECK-NOT: mcr1218; CHECK: ldab r0, [r[[ADDR]]]1219; CHECK-NOT: dmb1220; CHECK-NOT: mcr1221  ret i8 %val1222}1223 1224define i16 @test_atomic_load_monotonic_i16() nounwind {1225; CHECK-LABEL: test_atomic_load_monotonic_i16:1226  %val = load atomic i16, ptr @var16 monotonic, align 21227; CHECK-NOT: dmb1228; CHECK-NOT: mcr1229; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var161230; CHECK-NOT: dmb1231; CHECK-NOT: mcr1232; CHECK: movt r[[ADDR]], :upper16:var161233; CHECK-NOT: dmb1234; CHECK-NOT: mcr1235; CHECK: ldrh r0, [r[[ADDR]]]1236; CHECK-NOT: dmb1237; CHECK-NOT: mcr1238 1239  ret i16 %val1240}1241 1242define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {1243; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:1244  %addr_int = add i64 %base, %off1245  %addr = inttoptr i64 %addr_int to ptr1246 1247  %val = load atomic i32, ptr %addr monotonic, align 41248; CHECK-NOT: dmb1249; CHECK-NOT: mcr1250; CHECK-LE: ldr r0, [r0, r2]1251; CHECK-BE: ldr r0, [r1, r3]1252; CHECK-NOT: dmb1253; CHECK-NOT: mcr1254 1255  ret i32 %val1256}1257 1258define i64 @test_atomic_load_seq_cst_i64() nounwind {1259; CHECK-LABEL: test_atomic_load_seq_cst_i64:1260  %val = load atomic i64, ptr @var64 seq_cst, align 81261; CHECK-NOT: dmb1262; CHECK-NOT: mcr1263; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var641264; CHECK-NOT: dmb1265; CHECK-NOT: mcr1266; CHECK: movt r[[ADDR]], :upper16:var641267; CHECK-NOT: dmb1268; CHECK-NOT: mcr1269; CHECK: ldaexd r0, r1, [r[[ADDR]]]1270; CHECK-NOT: dmb1271; CHECK-NOT: mcr1272  ret i64 %val1273}1274 1275define void @test_atomic_store_monotonic_i8(i8 %val) nounwind {1276; CHECK-LABEL: test_atomic_store_monotonic_i8:1277  store atomic i8 %val, ptr @var8 monotonic, align 11278; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var81279; CHECK: movt r[[ADDR]], :upper16:var81280; CHECK: strb r0, [r[[ADDR]]]1281 1282  ret void1283}1284 1285define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {1286; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:1287 1288  %addr_int = add i64 %base, %off1289  %addr = inttoptr i64 %addr_int to ptr1290 1291  store atomic i8 %val, ptr %addr monotonic, align 11292; CHECK-LE: ldr{{b?(\.w)?}} [[VAL:r[0-9]+]], [sp]1293; CHECK-LE: strb [[VAL]], [r0, r2]1294; CHECK-BE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp, #3]1295; CHECK-BE: strb [[VAL]], [r1, r3]1296 1297  ret void1298}1299 1300define void @test_atomic_store_release_i8(i8 %val) nounwind {1301; CHECK-LABEL: test_atomic_store_release_i8:1302  store atomic i8 %val, ptr @var8 release, align 11303; CHECK-NOT: dmb1304; CHECK-NOT: mcr1305; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var81306; CHECK-NOT: dmb1307; CHECK-NOT: mcr1308; CHECK: movt r[[ADDR]], :upper16:var81309; CHECK-NOT: dmb1310; CHECK-NOT: mcr1311; CHECK: stlb r0, [r[[ADDR]]]1312; CHECK-NOT: dmb1313; CHECK-NOT: mcr1314  ret void1315}1316 1317define void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {1318; CHECK-LABEL: test_atomic_store_seq_cst_i8:1319  store atomic i8 %val, ptr @var8 seq_cst, align 11320; CHECK-NOT: dmb1321; CHECK-NOT: mcr1322; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var81323; CHECK-NOT: dmb1324; CHECK-NOT: mcr1325; CHECK: movt r[[ADDR]], :upper16:var81326; CHECK-NOT: dmb1327; CHECK-NOT: mcr1328; CHECK: stlb r0, [r[[ADDR]]]1329; CHECK-NOT: dmb1330; CHECK-NOT: mcr1331  ret void1332}1333 1334define void @test_atomic_store_monotonic_i16(i16 %val) nounwind {1335; CHECK-LABEL: test_atomic_store_monotonic_i16:1336  store atomic i16 %val, ptr @var16 monotonic, align 21337; CHECK-NOT: dmb1338; CHECK-NOT: mcr1339; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var161340; CHECK-NOT: dmb1341; CHECK-NOT: mcr1342; CHECK: movt r[[ADDR]], :upper16:var161343; CHECK-NOT: dmb1344; CHECK-NOT: mcr1345; CHECK: strh r0, [r[[ADDR]]]1346; CHECK-NOT: dmb1347; CHECK-NOT: mcr1348  ret void1349}1350 1351define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {1352; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:1353 1354  %addr_int = add i64 %base, %off1355  %addr = inttoptr i64 %addr_int to ptr1356 1357  store atomic i32 %val, ptr %addr monotonic, align 41358; CHECK-NOT: dmb1359; CHECK-NOT: mcr1360; CHECK: ldr [[VAL:r[0-9]+]], [sp]1361; CHECK-NOT: dmb1362; CHECK-NOT: mcr1363; CHECK-LE: str [[VAL]], [r0, r2]1364; CHECK-BE: str [[VAL]], [r1, r3]1365; CHECK-NOT: dmb1366; CHECK-NOT: mcr1367 1368  ret void1369}1370 1371define void @test_atomic_store_release_i64(i64 %val) nounwind {1372; CHECK-LABEL: test_atomic_store_release_i64:1373  store atomic i64 %val, ptr @var64 release, align 81374; CHECK-NOT: dmb1375; CHECK-NOT: mcr1376; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var641377; CHECK: movt [[ADDR]], :upper16:var641378 1379; CHECK: .LBB{{[0-9]+}}_1:1380  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the1381  ; function there.1382; CHECK: stlexd [[STATUS:r[0-9]+]], r0, r1, {{.*}}[[ADDR]]1383; CHECK-NEXT: cmp [[STATUS]], #01384; CHECK-NEXT: bne .LBB{{[0-9]+}}_11385; CHECK-NOT: dmb1386; CHECK-NOT: mcr1387 1388  ret void1389}1390 1391define i32 @not.barriers(ptr %var, i1 %cond) {1392; CHECK-LABEL: not.barriers:1393  br i1 %cond, label %atomic_ver, label %simple_ver1394simple_ver:1395  %oldval = load i32, ptr %var1396  %newval = add nsw i32 %oldval, -11397  store i32 %newval, ptr %var1398  br label %somewhere1399atomic_ver:1400  fence seq_cst1401  %val = atomicrmw add ptr %var, i32 -1 monotonic1402  fence seq_cst1403  br label %somewhere1404; CHECK: dmb1405; CHECK: ldrex1406; CHECK: dmb1407  ; The key point here is that the second dmb isn't immediately followed by the1408  ; simple_ver basic block, which LLVM attempted to do when DMB had been marked1409  ; with isBarrier. For now, look for something that looks like "somewhere".1410; CHECK-NEXT: {{mov|bx}}1411somewhere:1412  %combined = phi i32 [ %val, %atomic_ver ], [ %newval, %simple_ver]1413  ret i32 %combined1414}1415