brintos

brintos / llvm-project-archived public Read only

0
0
Text · 52.7 KiB · 4e09e76 Raw
1700 lines · plain
1; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 -disable-lsr -verify-machineinstrs -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTRICTALIGN %s2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+strict-align -aarch64-enable-atomic-cfg-tidy=0 -disable-lsr -verify-machineinstrs -o - %s | FileCheck --check-prefix=CHECK --check-prefix=STRICTALIGN %s3 4; This file contains tests for the AArch64 load/store optimizer.5 6%padding = type { ptr, ptr, ptr, ptr }7%s.byte = type { i8, i8 }8%s.halfword = type { i16, i16 }9%s.word = type { i32, i32 }10%s.doubleword = type { i64, i32 }11%s.quadword = type { fp128, i32 }12%s.float = type { float, i32 }13%s.double = type { double, i32 }14%struct.byte = type { %padding, %s.byte }15%struct.halfword = type { %padding, %s.halfword }16%struct.word = type { %padding, %s.word }17%struct.doubleword = type { %padding, %s.doubleword }18%struct.quadword = type { %padding, %s.quadword }19%struct.float = type { %padding, %s.float }20%struct.double = type { %padding, %s.double }21 22; Check the following transform:23;24; (ldr|str) X, [x0, #32]25;  ...26; add x0, x0, #3227;  ->28; (ldr|str) X, [x0, #32]!29;30; with X being either w1, x1, s0, d0 or q0.31 32declare void @bar_byte(ptr, i8)33 34define void @load-pre-indexed-byte(ptr %ptr) nounwind {35; CHECK-LABEL: load-pre-indexed-byte36; CHECK: ldrb w{{[0-9]+}}, [x{{[0-9]+}}, #32]!37entry:38  %a = getelementptr inbounds %struct.byte, ptr %ptr, i64 0, i32 1, i32 039  %add = load i8, ptr %a, align 440  br label %bar41bar:42  %c = getelementptr inbounds %struct.byte, ptr %ptr, i64 0, i32 143  tail call void @bar_byte(ptr %c, i8 %add)44  ret void45}46 47define void @store-pre-indexed-byte(ptr %ptr, i8 %val) nounwind {48; CHECK-LABEL: store-pre-indexed-byte49; CHECK: strb w{{[0-9]+}}, [x{{[0-9]+}}, #32]!50entry:51  %a = getelementptr inbounds %struct.byte, ptr %ptr, i64 0, i32 1, i32 052  store i8 %val, ptr %a, align 453  br label %bar54bar:55  %c = getelementptr inbounds %struct.byte, ptr %ptr, i64 0, i32 156  tail call void @bar_byte(ptr %c, i8 %val)57  ret void58}59 60declare void @bar_halfword(ptr, i16)61 62define void @load-pre-indexed-halfword(ptr %ptr) nounwind {63; CHECK-LABEL: load-pre-indexed-halfword64; CHECK: ldrh w{{[0-9]+}}, [x{{[0-9]+}}, #32]!65entry:66  %a = getelementptr inbounds %struct.halfword, ptr %ptr, i64 0, i32 1, i32 067  %add = load i16, ptr %a, align 468  br label %bar69bar:70  %c = getelementptr inbounds %struct.halfword, ptr %ptr, i64 0, i32 171  tail call void @bar_halfword(ptr %c, i16 %add)72  ret void73}74 75define void @store-pre-indexed-halfword(ptr %ptr, i16 %val) nounwind {76; CHECK-LABEL: store-pre-indexed-halfword77; CHECK: strh w{{[0-9]+}}, [x{{[0-9]+}}, #32]!78entry:79  %a = getelementptr inbounds %struct.halfword, ptr %ptr, i64 0, i32 1, i32 080  store i16 %val, ptr %a, align 481  br label %bar82bar:83  %c = getelementptr inbounds %struct.halfword, ptr %ptr, i64 0, i32 184  tail call void @bar_halfword(ptr %c, i16 %val)85  ret void86}87 88declare void @bar_word(ptr, i32)89 90define void @load-pre-indexed-word(ptr %ptr) nounwind {91; CHECK-LABEL: load-pre-indexed-word92; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #32]!93entry:94  %a = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1, i32 095  %add = load i32, ptr %a, align 496  br label %bar97bar:98  %c = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 199  tail call void @bar_word(ptr %c, i32 %add)100  ret void101}102 103define void @store-pre-indexed-word(ptr %ptr, i32 %val) nounwind {104; CHECK-LABEL: store-pre-indexed-word105; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #32]!106entry:107  %a = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1, i32 0108  store i32 %val, ptr %a, align 4109  br label %bar110bar:111  %c = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1112  tail call void @bar_word(ptr %c, i32 %val)113  ret void114}115 116declare void @bar_doubleword(ptr, i64)117 118define void @load-pre-indexed-doubleword(ptr %ptr) nounwind {119; CHECK-LABEL: load-pre-indexed-doubleword120; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #32]!121entry:122  %a = getelementptr inbounds %struct.doubleword, ptr %ptr, i64 0, i32 1, i32 0123  %add = load i64, ptr %a, align 8124  br label %bar125bar:126  %c = getelementptr inbounds %struct.doubleword, ptr %ptr, i64 0, i32 1127  tail call void @bar_doubleword(ptr %c, i64 %add)128  ret void129}130 131define void @store-pre-indexed-doubleword(ptr %ptr, i64 %val) nounwind {132; CHECK-LABEL: store-pre-indexed-doubleword133; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #32]!134entry:135  %a = getelementptr inbounds %struct.doubleword, ptr %ptr, i64 0, i32 1, i32 0136  store i64 %val, ptr %a, align 8137  br label %bar138bar:139  %c = getelementptr inbounds %struct.doubleword, ptr %ptr, i64 0, i32 1140  tail call void @bar_doubleword(ptr %c, i64 %val)141  ret void142}143 144declare void @bar_quadword(ptr, fp128)145 146define void @load-pre-indexed-quadword(ptr %ptr) nounwind {147; CHECK-LABEL: load-pre-indexed-quadword148; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #32]!149entry:150  %a = getelementptr inbounds %struct.quadword, ptr %ptr, i64 0, i32 1, i32 0151  %add = load fp128, ptr %a, align 16152  br label %bar153bar:154  %c = getelementptr inbounds %struct.quadword, ptr %ptr, i64 0, i32 1155  tail call void @bar_quadword(ptr %c, fp128 %add)156  ret void157}158 159define void @store-pre-indexed-quadword(ptr %ptr, fp128 %val) nounwind {160; CHECK-LABEL: store-pre-indexed-quadword161; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #32]!162entry:163  %a = getelementptr inbounds %struct.quadword, ptr %ptr, i64 0, i32 1, i32 0164  store fp128 %val, ptr %a, align 16165  br label %bar166bar:167  %c = getelementptr inbounds %struct.quadword, ptr %ptr, i64 0, i32 1168  tail call void @bar_quadword(ptr %c, fp128 %val)169  ret void170}171 172declare void @bar_float(ptr, float)173 174define void @load-pre-indexed-float(ptr %ptr) nounwind {175; CHECK-LABEL: load-pre-indexed-float176; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #32]!177entry:178  %a = getelementptr inbounds %struct.float, ptr %ptr, i64 0, i32 1, i32 0179  %add = load float, ptr %a, align 4180  br label %bar181bar:182  %c = getelementptr inbounds %struct.float, ptr %ptr, i64 0, i32 1183  tail call void @bar_float(ptr %c, float %add)184  ret void185}186 187define void @store-pre-indexed-float(ptr %ptr, float %val) nounwind {188; CHECK-LABEL: store-pre-indexed-float189; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #32]!190entry:191  %a = getelementptr inbounds %struct.float, ptr %ptr, i64 0, i32 1, i32 0192  store float %val, ptr %a, align 4193  br label %bar194bar:195  %c = getelementptr inbounds %struct.float, ptr %ptr, i64 0, i32 1196  tail call void @bar_float(ptr %c, float %val)197  ret void198}199 200declare void @bar_double(ptr, double)201 202define void @load-pre-indexed-double(ptr %ptr) nounwind {203; CHECK-LABEL: load-pre-indexed-double204; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #32]!205entry:206  %a = getelementptr inbounds %struct.double, ptr %ptr, i64 0, i32 1, i32 0207  %add = load double, ptr %a, align 8208  br label %bar209bar:210  %c = getelementptr inbounds %struct.double, ptr %ptr, i64 0, i32 1211  tail call void @bar_double(ptr %c, double %add)212  ret void213}214 215define void @store-pre-indexed-double(ptr %ptr, double %val) nounwind {216; CHECK-LABEL: store-pre-indexed-double217; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #32]!218entry:219  %a = getelementptr inbounds %struct.double, ptr %ptr, i64 0, i32 1, i32 0220  store double %val, ptr %a, align 8221  br label %bar222bar:223  %c = getelementptr inbounds %struct.double, ptr %ptr, i64 0, i32 1224  tail call void @bar_double(ptr %c, double %val)225  ret void226}227 228; Check the following transform:229;230; (ldp|stp) w1, w2 [x0, #32]231;  ...232; add x0, x0, #32233;  ->234; (ldp|stp) w1, w2, [x0, #32]!235;236 237define void @load-pair-pre-indexed-word(ptr %ptr) nounwind {238; CHECK-LABEL: load-pair-pre-indexed-word239; CHECK: ldp w{{[0-9]+}}, w{{[0-9]+}}, [x0, #32]!240; CHECK-NOT: add x0, x0, #32241entry:242  %a = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1, i32 0243  %a1 = load i32, ptr %a, align 4244  %b = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1, i32 1245  %b1 = load i32, ptr %b, align 4246  %add = add i32 %a1, %b1247  br label %bar248bar:249  %c = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1250  tail call void @bar_word(ptr %c, i32 %add)251  ret void252}253 254define void @store-pair-pre-indexed-word(ptr %ptr, i32 %val) nounwind {255; CHECK-LABEL: store-pair-pre-indexed-word256; CHECK: stp w{{[0-9]+}}, w{{[0-9]+}}, [x0, #32]!257; CHECK-NOT: add x0, x0, #32258entry:259  %a = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1, i32 0260  store i32 %val, ptr %a, align 4261  %b = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1, i32 1262  store i32 %val, ptr %b, align 4263  br label %bar264bar:265  %c = getelementptr inbounds %struct.word, ptr %ptr, i64 0, i32 1266  tail call void @bar_word(ptr %c, i32 %val)267  ret void268}269 270; Check the following transform:271;272; add x8, x8, #16273;  ...274; ldr X, [x8]275;  ->276; ldr X, [x8, #16]!277;278; with X being either w0, x0, s0, d0 or q0.279 280%pre.struct.i32 = type { i32, i32, i32, i32, i32}281%pre.struct.i64 = type { i32, i64, i64, i64, i64}282%pre.struct.i128 = type { i32, <2 x i64>, <2 x i64>, <2 x i64>}283%pre.struct.float = type { i32, float, float, float}284%pre.struct.double = type { i32, double, double, double}285 286define i32 @load-pre-indexed-word2(ptr %this, i1 %cond,287                                   ptr %load2) nounwind {288; CHECK-LABEL: load-pre-indexed-word2289; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #4]!290  br i1 %cond, label %if.then, label %if.end291if.then:292  %load1 = load ptr, ptr %this293  %gep1 = getelementptr inbounds %pre.struct.i32, ptr %load1, i64 0, i32 1294  br label %return295if.end:296  %gep2 = getelementptr inbounds %pre.struct.i32, ptr %load2, i64 0, i32 2297  br label %return298return:299  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]300  %ret = load i32, ptr %retptr301  ret i32 %ret302}303 304define i64 @load-pre-indexed-doubleword2(ptr %this, i1 %cond,305                                         ptr %load2) nounwind {306; CHECK-LABEL: load-pre-indexed-doubleword2307; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #8]!308  br i1 %cond, label %if.then, label %if.end309if.then:310  %load1 = load ptr, ptr %this311  %gep1 = getelementptr inbounds %pre.struct.i64, ptr %load1, i64 0, i32 1312  br label %return313if.end:314  %gep2 = getelementptr inbounds %pre.struct.i64, ptr %load2, i64 0, i32 2315  br label %return316return:317  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]318  %ret = load i64, ptr %retptr319  ret i64 %ret320}321 322define <2 x i64> @load-pre-indexed-quadword2(ptr %this, i1 %cond,323                                             ptr %load2) nounwind {324; CHECK-LABEL: load-pre-indexed-quadword2325; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #16]!326  br i1 %cond, label %if.then, label %if.end327if.then:328  %load1 = load ptr, ptr %this329  %gep1 = getelementptr inbounds %pre.struct.i128, ptr %load1, i64 0, i32 1330  br label %return331if.end:332  %gep2 = getelementptr inbounds %pre.struct.i128, ptr %load2, i64 0, i32 2333  br label %return334return:335  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]336  %ret = load <2 x i64>, ptr %retptr337  ret <2 x i64> %ret338}339 340define float @load-pre-indexed-float2(ptr %this, i1 %cond,341                                      ptr %load2) nounwind {342; CHECK-LABEL: load-pre-indexed-float2343; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #4]!344  br i1 %cond, label %if.then, label %if.end345if.then:346  %load1 = load ptr, ptr %this347  %gep1 = getelementptr inbounds %pre.struct.float, ptr %load1, i64 0, i32 1348  br label %return349if.end:350  %gep2 = getelementptr inbounds %pre.struct.float, ptr %load2, i64 0, i32 2351  br label %return352return:353  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]354  %ret = load float, ptr %retptr355  ret float %ret356}357 358define double @load-pre-indexed-double2(ptr %this, i1 %cond,359                                        ptr %load2) nounwind {360; CHECK-LABEL: load-pre-indexed-double2361; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #8]!362  br i1 %cond, label %if.then, label %if.end363if.then:364  %load1 = load ptr, ptr %this365  %gep1 = getelementptr inbounds %pre.struct.double, ptr %load1, i64 0, i32 1366  br label %return367if.end:368  %gep2 = getelementptr inbounds %pre.struct.double, ptr %load2, i64 0, i32 2369  br label %return370return:371  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]372  %ret = load double, ptr %retptr373  ret double %ret374}375 376define i32 @load-pre-indexed-word3(ptr %this, i1 %cond,377                                   ptr %load2) nounwind {378; CHECK-LABEL: load-pre-indexed-word3379; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #12]!380  br i1 %cond, label %if.then, label %if.end381if.then:382  %load1 = load ptr, ptr %this383  %gep1 = getelementptr inbounds %pre.struct.i32, ptr %load1, i64 0, i32 3384  br label %return385if.end:386  %gep2 = getelementptr inbounds %pre.struct.i32, ptr %load2, i64 0, i32 4387  br label %return388return:389  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]390  %ret = load i32, ptr %retptr391  ret i32 %ret392}393 394define i64 @load-pre-indexed-doubleword3(ptr %this, i1 %cond,395                                         ptr %load2) nounwind {396; CHECK-LABEL: load-pre-indexed-doubleword3397; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #16]!398  br i1 %cond, label %if.then, label %if.end399if.then:400  %load1 = load ptr, ptr %this401  %gep1 = getelementptr inbounds %pre.struct.i64, ptr %load1, i64 0, i32 2402  br label %return403if.end:404  %gep2 = getelementptr inbounds %pre.struct.i64, ptr %load2, i64 0, i32 3405  br label %return406return:407  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]408  %ret = load i64, ptr %retptr409  ret i64 %ret410}411 412define <2 x i64> @load-pre-indexed-quadword3(ptr %this, i1 %cond,413                                             ptr %load2) nounwind {414; CHECK-LABEL: load-pre-indexed-quadword3415; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #32]!416  br i1 %cond, label %if.then, label %if.end417if.then:418  %load1 = load ptr, ptr %this419  %gep1 = getelementptr inbounds %pre.struct.i128, ptr %load1, i64 0, i32 2420  br label %return421if.end:422  %gep2 = getelementptr inbounds %pre.struct.i128, ptr %load2, i64 0, i32 3423  br label %return424return:425  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]426  %ret = load <2 x i64>, ptr %retptr427  ret <2 x i64> %ret428}429 430define float @load-pre-indexed-float3(ptr %this, i1 %cond,431                                      ptr %load2) nounwind {432; CHECK-LABEL: load-pre-indexed-float3433; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #8]!434  br i1 %cond, label %if.then, label %if.end435if.then:436  %load1 = load ptr, ptr %this437  %gep1 = getelementptr inbounds %pre.struct.float, ptr %load1, i64 0, i32 2438  br label %return439if.end:440  %gep2 = getelementptr inbounds %pre.struct.float, ptr %load2, i64 0, i32 3441  br label %return442return:443  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]444  %ret = load float, ptr %retptr445  ret float %ret446}447 448define double @load-pre-indexed-double3(ptr %this, i1 %cond,449                                        ptr %load2) nounwind {450; CHECK-LABEL: load-pre-indexed-double3451; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #16]!452  br i1 %cond, label %if.then, label %if.end453if.then:454  %load1 = load ptr, ptr %this455  %gep1 = getelementptr inbounds %pre.struct.double, ptr %load1, i64 0, i32 2456  br label %return457if.end:458  %gep2 = getelementptr inbounds %pre.struct.double, ptr %load2, i64 0, i32 3459  br label %return460return:461  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]462  %ret = load double, ptr %retptr463  ret double %ret464}465 466; Check the following transform:467;468; add x8, x8, #16469;  ...470; str X, [x8]471;  ->472; str X, [x8, #16]!473;474; with X being either w0, x0, s0, d0 or q0.475 476define void @store-pre-indexed-word2(ptr %this, i1 %cond,477                                     ptr %load2,478                                     i32 %val) nounwind {479; CHECK-LABEL: store-pre-indexed-word2480; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #4]!481  br i1 %cond, label %if.then, label %if.end482if.then:483  %load1 = load ptr, ptr %this484  %gep1 = getelementptr inbounds %pre.struct.i32, ptr %load1, i64 0, i32 1485  br label %return486if.end:487  %gep2 = getelementptr inbounds %pre.struct.i32, ptr %load2, i64 0, i32 2488  br label %return489return:490  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]491  store i32 %val, ptr %retptr492  ret void493}494 495define void @store-pre-indexed-doubleword2(ptr %this, i1 %cond,496                                           ptr %load2,497                                           i64 %val) nounwind {498; CHECK-LABEL: store-pre-indexed-doubleword2499; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #8]!500  br i1 %cond, label %if.then, label %if.end501if.then:502  %load1 = load ptr, ptr %this503  %gep1 = getelementptr inbounds %pre.struct.i64, ptr %load1, i64 0, i32 1504  br label %return505if.end:506  %gep2 = getelementptr inbounds %pre.struct.i64, ptr %load2, i64 0, i32 2507  br label %return508return:509  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]510  store i64 %val, ptr %retptr511  ret void512}513 514define void @store-pre-indexed-quadword2(ptr %this, i1 %cond,515                                         ptr %load2,516                                         <2 x i64> %val) nounwind {517; CHECK-LABEL: store-pre-indexed-quadword2518; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #16]!519  br i1 %cond, label %if.then, label %if.end520if.then:521  %load1 = load ptr, ptr %this522  %gep1 = getelementptr inbounds %pre.struct.i128, ptr %load1, i64 0, i32 1523  br label %return524if.end:525  %gep2 = getelementptr inbounds %pre.struct.i128, ptr %load2, i64 0, i32 2526  br label %return527return:528  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]529  store <2 x i64> %val, ptr %retptr530  ret void531}532 533define void @store-pre-indexed-float2(ptr %this, i1 %cond,534                                      ptr %load2,535                                      float %val) nounwind {536; CHECK-LABEL: store-pre-indexed-float2537; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #4]!538  br i1 %cond, label %if.then, label %if.end539if.then:540  %load1 = load ptr, ptr %this541  %gep1 = getelementptr inbounds %pre.struct.float, ptr %load1, i64 0, i32 1542  br label %return543if.end:544  %gep2 = getelementptr inbounds %pre.struct.float, ptr %load2, i64 0, i32 2545  br label %return546return:547  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]548  store float %val, ptr %retptr549  ret void550}551 552define void @store-pre-indexed-double2(ptr %this, i1 %cond,553                                      ptr %load2,554                                      double %val) nounwind {555; CHECK-LABEL: store-pre-indexed-double2556; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #8]!557  br i1 %cond, label %if.then, label %if.end558if.then:559  %load1 = load ptr, ptr %this560  %gep1 = getelementptr inbounds %pre.struct.double, ptr %load1, i64 0, i32 1561  br label %return562if.end:563  %gep2 = getelementptr inbounds %pre.struct.double, ptr %load2, i64 0, i32 2564  br label %return565return:566  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]567  store double %val, ptr %retptr568  ret void569}570 571define void @store-pre-indexed-word3(ptr %this, i1 %cond,572                                     ptr %load2,573                                     i32 %val) nounwind {574; CHECK-LABEL: store-pre-indexed-word3575; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #12]!576  br i1 %cond, label %if.then, label %if.end577if.then:578  %load1 = load ptr, ptr %this579  %gep1 = getelementptr inbounds %pre.struct.i32, ptr %load1, i64 0, i32 3580  br label %return581if.end:582  %gep2 = getelementptr inbounds %pre.struct.i32, ptr %load2, i64 0, i32 4583  br label %return584return:585  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]586  store i32 %val, ptr %retptr587  ret void588}589 590define void @store-pre-indexed-doubleword3(ptr %this, i1 %cond,591                                           ptr %load2,592                                           i64 %val) nounwind {593; CHECK-LABEL: store-pre-indexed-doubleword3594; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #24]!595  br i1 %cond, label %if.then, label %if.end596if.then:597  %load1 = load ptr, ptr %this598  %gep1 = getelementptr inbounds %pre.struct.i64, ptr %load1, i64 0, i32 3599  br label %return600if.end:601  %gep2 = getelementptr inbounds %pre.struct.i64, ptr %load2, i64 0, i32 4602  br label %return603return:604  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]605  store i64 %val, ptr %retptr606  ret void607}608 609define void @store-pre-indexed-quadword3(ptr %this, i1 %cond,610                                         ptr %load2,611                                         <2 x i64> %val) nounwind {612; CHECK-LABEL: store-pre-indexed-quadword3613; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #32]!614  br i1 %cond, label %if.then, label %if.end615if.then:616  %load1 = load ptr, ptr %this617  %gep1 = getelementptr inbounds %pre.struct.i128, ptr %load1, i64 0, i32 2618  br label %return619if.end:620  %gep2 = getelementptr inbounds %pre.struct.i128, ptr %load2, i64 0, i32 3621  br label %return622return:623  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]624  store <2 x i64> %val, ptr %retptr625  ret void626}627 628define void @store-pre-indexed-float3(ptr %this, i1 %cond,629                                      ptr %load2,630                                      float %val) nounwind {631; CHECK-LABEL: store-pre-indexed-float3632; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #8]!633  br i1 %cond, label %if.then, label %if.end634if.then:635  %load1 = load ptr, ptr %this636  %gep1 = getelementptr inbounds %pre.struct.float, ptr %load1, i64 0, i32 2637  br label %return638if.end:639  %gep2 = getelementptr inbounds %pre.struct.float, ptr %load2, i64 0, i32 3640  br label %return641return:642  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]643  store float %val, ptr %retptr644  ret void645}646 647define void @store-pre-indexed-double3(ptr %this, i1 %cond,648                                      ptr %load2,649                                      double %val) nounwind {650; CHECK-LABEL: store-pre-indexed-double3651; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #16]!652  br i1 %cond, label %if.then, label %if.end653if.then:654  %load1 = load ptr, ptr %this655  %gep1 = getelementptr inbounds %pre.struct.double, ptr %load1, i64 0, i32 2656  br label %return657if.end:658  %gep2 = getelementptr inbounds %pre.struct.double, ptr %load2, i64 0, i32 3659  br label %return660return:661  %retptr = phi ptr [ %gep1, %if.then ], [ %gep2, %if.end ]662  store double %val, ptr %retptr663  ret void664}665 666; Check the following transform:667;668; ldr X, [x20]669;  ...670; add x20, x20, #32671;  ->672; ldr X, [x20], #32673;674; with X being either w0, x0, s0, d0 or q0.675 676define void @load-post-indexed-byte(ptr %array, i64 %count) nounwind {677; CHECK-LABEL: load-post-indexed-byte678; CHECK: ldrb w{{[0-9]+}}, [x{{[0-9]+}}], #4679entry:680  %gep1 = getelementptr i8, ptr %array, i64 2681  br label %body682 683body:684  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]685  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]686  %gep2 = getelementptr i8, ptr %iv2, i64 -1687  %load = load i8, ptr %gep2688  call void @use-byte(i8 %load)689  %load2 = load i8, ptr %iv2690  call void @use-byte(i8 %load2)691  %iv.next = add i64 %iv, -4692  %gep3 = getelementptr i8, ptr %iv2, i64 4693  %cond = icmp eq i64 %iv.next, 0694  br i1 %cond, label %exit, label %body695 696exit:697  ret void698}699 700define void @load-post-indexed-halfword(ptr %array, i64 %count) nounwind {701; CHECK-LABEL: load-post-indexed-halfword702; CHECK: ldrh w{{[0-9]+}}, [x{{[0-9]+}}], #8703entry:704  %gep1 = getelementptr i16, ptr %array, i64 2705  br label %body706 707body:708  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]709  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]710  %gep2 = getelementptr i16, ptr %iv2, i64 -1711  %load = load i16, ptr %gep2712  call void @use-halfword(i16 %load)713  %load2 = load i16, ptr %iv2714  call void @use-halfword(i16 %load2)715  %iv.next = add i64 %iv, -4716  %gep3 = getelementptr i16, ptr %iv2, i64 4717  %cond = icmp eq i64 %iv.next, 0718  br i1 %cond, label %exit, label %body719 720exit:721  ret void722}723 724define void @load-post-indexed-word(ptr %array, i64 %count) nounwind {725; CHECK-LABEL: load-post-indexed-word726; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #16727entry:728  %gep1 = getelementptr i32, ptr %array, i64 2729  br label %body730 731body:732  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]733  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]734  %gep2 = getelementptr i32, ptr %iv2, i64 -1735  %load = load i32, ptr %gep2736  call void @use-word(i32 %load)737  %load2 = load i32, ptr %iv2738  call void @use-word(i32 %load2)739  %iv.next = add i64 %iv, -4740  %gep3 = getelementptr i32, ptr %iv2, i64 4741  %cond = icmp eq i64 %iv.next, 0742  br i1 %cond, label %exit, label %body743 744exit:745  ret void746}747 748define void @load-post-indexed-doubleword(ptr %array, i64 %count) nounwind {749; CHECK-LABEL: load-post-indexed-doubleword750; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #32751entry:752  %gep1 = getelementptr i64, ptr %array, i64 2753  br label %body754 755body:756  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]757  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]758  %gep2 = getelementptr i64, ptr %iv2, i64 -1759  %load = load i64, ptr %gep2760  call void @use-doubleword(i64 %load)761  %load2 = load i64, ptr %iv2762  call void @use-doubleword(i64 %load2)763  %iv.next = add i64 %iv, -4764  %gep3 = getelementptr i64, ptr %iv2, i64 4765  %cond = icmp eq i64 %iv.next, 0766  br i1 %cond, label %exit, label %body767 768exit:769  ret void770}771 772define void @load-post-indexed-quadword(ptr %array, i64 %count) nounwind {773; CHECK-LABEL: load-post-indexed-quadword774; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}], #64775entry:776  %gep1 = getelementptr <2 x i64>, ptr %array, i64 2777  br label %body778 779body:780  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]781  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]782  %gep2 = getelementptr <2 x i64>, ptr %iv2, i64 -1783  %load = load <2 x i64>, ptr %gep2784  call void @use-quadword(<2 x i64> %load)785  %load2 = load <2 x i64>, ptr %iv2786  call void @use-quadword(<2 x i64> %load2)787  %iv.next = add i64 %iv, -4788  %gep3 = getelementptr <2 x i64>, ptr %iv2, i64 4789  %cond = icmp eq i64 %iv.next, 0790  br i1 %cond, label %exit, label %body791 792exit:793  ret void794}795 796define void @load-post-indexed-float(ptr %array, i64 %count) nounwind {797; CHECK-LABEL: load-post-indexed-float798; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}], #16799entry:800  %gep1 = getelementptr float, ptr %array, i64 2801  br label %body802 803body:804  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]805  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]806  %gep2 = getelementptr float, ptr %iv2, i64 -1807  %load = load float, ptr %gep2808  call void @use-float(float %load)809  %load2 = load float, ptr %iv2810  call void @use-float(float %load2)811  %iv.next = add i64 %iv, -4812  %gep3 = getelementptr float, ptr %iv2, i64 4813  %cond = icmp eq i64 %iv.next, 0814  br i1 %cond, label %exit, label %body815 816exit:817  ret void818}819 820define void @load-post-indexed-double(ptr %array, i64 %count) nounwind {821; CHECK-LABEL: load-post-indexed-double822; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}], #32823entry:824  %gep1 = getelementptr double, ptr %array, i64 2825  br label %body826 827body:828  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]829  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]830  %gep2 = getelementptr double, ptr %iv2, i64 -1831  %load = load double, ptr %gep2832  call void @use-double(double %load)833  %load2 = load double, ptr %iv2834  call void @use-double(double %load2)835  %iv.next = add i64 %iv, -4836  %gep3 = getelementptr double, ptr %iv2, i64 4837  %cond = icmp eq i64 %iv.next, 0838  br i1 %cond, label %exit, label %body839 840exit:841  ret void842}843 844; Check the following transform:845;846; str X, [x20]847;  ...848; add x20, x20, #32849;  ->850; str X, [x20], #32851;852; with X being either w0, x0, s0, d0 or q0.853 854define void @store-post-indexed-byte(ptr %array, i64 %count, i8 %val) nounwind {855; CHECK-LABEL: store-post-indexed-byte856; CHECK: strb w{{[0-9]+}}, [x{{[0-9]+}}], #4857entry:858  %gep1 = getelementptr i8, ptr %array, i64 2859  br label %body860 861body:862  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]863  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]864  %gep2 = getelementptr i8, ptr %iv2, i64 -1865  %load = load i8, ptr %gep2866  call void @use-byte(i8 %load)867  store i8 %val, ptr %iv2868  %iv.next = add i64 %iv, -4869  %gep3 = getelementptr i8, ptr %iv2, i64 4870  %cond = icmp eq i64 %iv.next, 0871  br i1 %cond, label %exit, label %body872 873exit:874  ret void875}876 877define void @store-post-indexed-halfword(ptr %array, i64 %count, i16 %val) nounwind {878; CHECK-LABEL: store-post-indexed-halfword879; CHECK: strh w{{[0-9]+}}, [x{{[0-9]+}}], #8880entry:881  %gep1 = getelementptr i16, ptr %array, i64 2882  br label %body883 884body:885  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]886  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]887  %gep2 = getelementptr i16, ptr %iv2, i64 -1888  %load = load i16, ptr %gep2889  call void @use-halfword(i16 %load)890  store i16 %val, ptr %iv2891  %iv.next = add i64 %iv, -4892  %gep3 = getelementptr i16, ptr %iv2, i64 4893  %cond = icmp eq i64 %iv.next, 0894  br i1 %cond, label %exit, label %body895 896exit:897  ret void898}899 900define void @store-post-indexed-word(ptr %array, i64 %count, i32 %val) nounwind {901; CHECK-LABEL: store-post-indexed-word902; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #16903entry:904  %gep1 = getelementptr i32, ptr %array, i64 2905  br label %body906 907body:908  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]909  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]910  %gep2 = getelementptr i32, ptr %iv2, i64 -1911  %load = load i32, ptr %gep2912  call void @use-word(i32 %load)913  store i32 %val, ptr %iv2914  %iv.next = add i64 %iv, -4915  %gep3 = getelementptr i32, ptr %iv2, i64 4916  %cond = icmp eq i64 %iv.next, 0917  br i1 %cond, label %exit, label %body918 919exit:920  ret void921}922 923define void @store-post-indexed-doubleword(ptr %array, i64 %count, i64 %val) nounwind {924; CHECK-LABEL: store-post-indexed-doubleword925; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #32926entry:927  %gep1 = getelementptr i64, ptr %array, i64 2928  br label %body929 930body:931  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]932  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]933  %gep2 = getelementptr i64, ptr %iv2, i64 -1934  %load = load i64, ptr %gep2935  call void @use-doubleword(i64 %load)936  store i64 %val, ptr %iv2937  %iv.next = add i64 %iv, -4938  %gep3 = getelementptr i64, ptr %iv2, i64 4939  %cond = icmp eq i64 %iv.next, 0940  br i1 %cond, label %exit, label %body941 942exit:943  ret void944}945 946define void @store-post-indexed-quadword(ptr %array, i64 %count, <2 x i64> %val) nounwind {947; CHECK-LABEL: store-post-indexed-quadword948; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}], #64949entry:950  %gep1 = getelementptr <2 x i64>, ptr %array, i64 2951  br label %body952 953body:954  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]955  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]956  %gep2 = getelementptr <2 x i64>, ptr %iv2, i64 -1957  %load = load <2 x i64>, ptr %gep2958  call void @use-quadword(<2 x i64> %load)959  store <2 x i64> %val, ptr %iv2960  %iv.next = add i64 %iv, -4961  %gep3 = getelementptr <2 x i64>, ptr %iv2, i64 4962  %cond = icmp eq i64 %iv.next, 0963  br i1 %cond, label %exit, label %body964 965exit:966  ret void967}968 969define void @store-post-indexed-float(ptr %array, i64 %count, float %val) nounwind {970; CHECK-LABEL: store-post-indexed-float971; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}], #16972entry:973  %gep1 = getelementptr float, ptr %array, i64 2974  br label %body975 976body:977  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]978  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]979  %gep2 = getelementptr float, ptr %iv2, i64 -1980  %load = load float, ptr %gep2981  call void @use-float(float %load)982  store float %val, ptr %iv2983  %iv.next = add i64 %iv, -4984  %gep3 = getelementptr float, ptr %iv2, i64 4985  %cond = icmp eq i64 %iv.next, 0986  br i1 %cond, label %exit, label %body987 988exit:989  ret void990}991 992define void @store-post-indexed-double(ptr %array, i64 %count, double %val) nounwind {993; CHECK-LABEL: store-post-indexed-double994; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}], #32995entry:996  %gep1 = getelementptr double, ptr %array, i64 2997  br label %body998 999body:1000  %iv2 = phi ptr [ %gep3, %body ], [ %gep1, %entry ]1001  %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]1002  %gep2 = getelementptr double, ptr %iv2, i64 -11003  %load = load double, ptr %gep21004  call void @use-double(double %load)1005  store double %val, ptr %iv21006  %iv.next = add i64 %iv, -41007  %gep3 = getelementptr double, ptr %iv2, i64 41008  %cond = icmp eq i64 %iv.next, 01009  br i1 %cond, label %exit, label %body1010 1011exit:1012  ret void1013}1014 1015declare void @use-byte(i8)1016declare void @use-halfword(i16)1017declare void @use-word(i32)1018declare void @use-doubleword(i64)1019declare void @use-quadword(<2 x i64>)1020declare void @use-float(float)1021declare void @use-double(double)1022 1023; Check the following transform:1024;1025; stp w0, [x20]1026;  ...1027; add x20, x20, #321028;  ->1029; stp w0, [x20], #321030 1031define void @store-pair-post-indexed-word() nounwind {1032; CHECK-LABEL: store-pair-post-indexed-word1033; CHECK: stp w{{[0-9]+}}, w{{[0-9]+}}, [sp], #161034; CHECK: ret1035  %src = alloca { i32, i32 }, align 81036  %dst = alloca { i32, i32 }, align 81037 1038  %src.realp = getelementptr inbounds { i32, i32 }, ptr %src, i32 0, i32 01039  %src.real = load i32, ptr %src.realp1040  %src.imagp = getelementptr inbounds { i32, i32 }, ptr %src, i32 0, i32 11041  %src.imag = load i32, ptr %src.imagp1042 1043  %dst.realp = getelementptr inbounds { i32, i32 }, ptr %dst, i32 0, i32 01044  %dst.imagp = getelementptr inbounds { i32, i32 }, ptr %dst, i32 0, i32 11045  store i32 %src.real, ptr %dst.realp1046  store i32 %src.imag, ptr %dst.imagp1047  ret void1048}1049 1050define void @store-pair-post-indexed-doubleword() nounwind {1051; CHECK-LABEL: store-pair-post-indexed-doubleword1052; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [sp], #321053; CHECK: ret1054  %src = alloca { i64, i64 }, align 81055  %dst = alloca { i64, i64 }, align 81056 1057  %src.realp = getelementptr inbounds { i64, i64 }, ptr %src, i32 0, i32 01058  %src.real = load i64, ptr %src.realp1059  %src.imagp = getelementptr inbounds { i64, i64 }, ptr %src, i32 0, i32 11060  %src.imag = load i64, ptr %src.imagp1061 1062  %dst.realp = getelementptr inbounds { i64, i64 }, ptr %dst, i32 0, i32 01063  %dst.imagp = getelementptr inbounds { i64, i64 }, ptr %dst, i32 0, i32 11064  store i64 %src.real, ptr %dst.realp1065  store i64 %src.imag, ptr %dst.imagp1066  ret void1067}1068 1069define void @store-pair-post-indexed-float() nounwind {1070; CHECK-LABEL: store-pair-post-indexed-float1071; CHECK: stp s{{[0-9]+}}, s{{[0-9]+}}, [sp], #161072; CHECK: ret1073  %src = alloca { float, float }, align 81074  %dst = alloca { float, float }, align 81075 1076  %src.realp = getelementptr inbounds { float, float }, ptr %src, i32 0, i32 01077  %src.real = load float, ptr %src.realp1078  %src.imagp = getelementptr inbounds { float, float }, ptr %src, i32 0, i32 11079  %src.imag = load float, ptr %src.imagp1080 1081  %dst.realp = getelementptr inbounds { float, float }, ptr %dst, i32 0, i32 01082  %dst.imagp = getelementptr inbounds { float, float }, ptr %dst, i32 0, i32 11083  store float %src.real, ptr %dst.realp1084  store float %src.imag, ptr %dst.imagp1085  ret void1086}1087 1088define void @store-pair-post-indexed-double() nounwind {1089; CHECK-LABEL: store-pair-post-indexed-double1090; CHECK: stp d{{[0-9]+}}, d{{[0-9]+}}, [sp], #321091; CHECK: ret1092  %src = alloca { double, double }, align 81093  %dst = alloca { double, double }, align 81094 1095  %src.realp = getelementptr inbounds { double, double }, ptr %src, i32 0, i32 01096  %src.real = load double, ptr %src.realp1097  %src.imagp = getelementptr inbounds { double, double }, ptr %src, i32 0, i32 11098  %src.imag = load double, ptr %src.imagp1099 1100  %dst.realp = getelementptr inbounds { double, double }, ptr %dst, i32 0, i32 01101  %dst.imagp = getelementptr inbounds { double, double }, ptr %dst, i32 0, i32 11102  store double %src.real, ptr %dst.realp1103  store double %src.imag, ptr %dst.imagp1104  ret void1105}1106 1107; Check the following transform:1108;1109; (ldr|str) X, [x20]1110;  ...1111; sub x20, x20, #161112;  ->1113; (ldr|str) X, [x20], #-161114;1115; with X being either w0, x0, s0, d0 or q0.1116 1117define void @post-indexed-sub-word(ptr %a, ptr %b, i64 %count) nounwind {1118; CHECK-LABEL: post-indexed-sub-word1119; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #-81120; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #-81121  br label %for.body1122for.body:1123  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1124  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1125  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1126  %gep1 = getelementptr i32, ptr %phi1, i64 -11127  %load1 = load i32, ptr %gep11128  %gep2 = getelementptr i32, ptr %phi2, i64 -11129  store i32 %load1, ptr %gep21130  %load2 = load i32, ptr %phi11131  store i32 %load2, ptr %phi21132  %dec.i = add nsw i64 %i, -11133  %gep3 = getelementptr i32, ptr %phi2, i64 -21134  %gep4 = getelementptr i32, ptr %phi1, i64 -21135  %cond = icmp sgt i64 %dec.i, 01136  br i1 %cond, label %for.body, label %end1137end:1138  ret void1139}1140 1141define void @post-indexed-sub-doubleword(ptr %a, ptr %b, i64 %count) nounwind {1142; CHECK-LABEL: post-indexed-sub-doubleword1143; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #-161144; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #-161145  br label %for.body1146for.body:1147  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1148  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1149  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1150  %gep1 = getelementptr i64, ptr %phi1, i64 -11151  %load1 = load i64, ptr %gep11152  %gep2 = getelementptr i64, ptr %phi2, i64 -11153  store i64 %load1, ptr %gep21154  %load2 = load i64, ptr %phi11155  store i64 %load2, ptr %phi21156  %dec.i = add nsw i64 %i, -11157  %gep3 = getelementptr i64, ptr %phi2, i64 -21158  %gep4 = getelementptr i64, ptr %phi1, i64 -21159  %cond = icmp sgt i64 %dec.i, 01160  br i1 %cond, label %for.body, label %end1161end:1162  ret void1163}1164 1165define void @post-indexed-sub-quadword(ptr %a, ptr %b, i64 %count) nounwind {1166; CHECK-LABEL: post-indexed-sub-quadword1167; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}], #-321168; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}], #-321169  br label %for.body1170for.body:1171  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1172  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1173  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1174  %gep1 = getelementptr <2 x i64>, ptr %phi1, i64 -11175  %load1 = load <2 x i64>, ptr %gep11176  %gep2 = getelementptr <2 x i64>, ptr %phi2, i64 -11177  store <2 x i64> %load1, ptr %gep21178  %load2 = load <2 x i64>, ptr %phi11179  store <2 x i64> %load2, ptr %phi21180  %dec.i = add nsw i64 %i, -11181  %gep3 = getelementptr <2 x i64>, ptr %phi2, i64 -21182  %gep4 = getelementptr <2 x i64>, ptr %phi1, i64 -21183  %cond = icmp sgt i64 %dec.i, 01184  br i1 %cond, label %for.body, label %end1185end:1186  ret void1187}1188 1189define void @post-indexed-sub-float(ptr %a, ptr %b, i64 %count) nounwind {1190; CHECK-LABEL: post-indexed-sub-float1191; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}], #-81192; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}], #-81193  br label %for.body1194for.body:1195  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1196  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1197  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1198  %gep1 = getelementptr float, ptr %phi1, i64 -11199  %load1 = load float, ptr %gep11200  %gep2 = getelementptr float, ptr %phi2, i64 -11201  store float %load1, ptr %gep21202  %load2 = load float, ptr %phi11203  store float %load2, ptr %phi21204  %dec.i = add nsw i64 %i, -11205  %gep3 = getelementptr float, ptr %phi2, i64 -21206  %gep4 = getelementptr float, ptr %phi1, i64 -21207  %cond = icmp sgt i64 %dec.i, 01208  br i1 %cond, label %for.body, label %end1209end:1210  ret void1211}1212 1213define void @post-indexed-sub-double(ptr %a, ptr %b, i64 %count) nounwind {1214; CHECK-LABEL: post-indexed-sub-double1215; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}], #-161216; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}], #-161217  br label %for.body1218for.body:1219  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1220  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1221  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1222  %gep1 = getelementptr double, ptr %phi1, i64 -11223  %load1 = load double, ptr %gep11224  %gep2 = getelementptr double, ptr %phi2, i64 -11225  store double %load1, ptr %gep21226  %load2 = load double, ptr %phi11227  store double %load2, ptr %phi21228  %dec.i = add nsw i64 %i, -11229  %gep3 = getelementptr double, ptr %phi2, i64 -21230  %gep4 = getelementptr double, ptr %phi1, i64 -21231  %cond = icmp sgt i64 %dec.i, 01232  br i1 %cond, label %for.body, label %end1233end:1234  ret void1235}1236 1237define void @post-indexed-sub-doubleword-offset-min(ptr %a, ptr %b, i64 %count) nounwind {1238; CHECK-LABEL: post-indexed-sub-doubleword-offset-min1239; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #-2561240; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #-2561241  br label %for.body1242for.body:1243  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1244  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1245  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1246  %gep1 = getelementptr i64, ptr %phi1, i64 11247  %load1 = load i64, ptr %gep11248  %gep2 = getelementptr i64, ptr %phi2, i64 11249  store i64 %load1, ptr %gep21250  %load2 = load i64, ptr %phi11251  store i64 %load2, ptr %phi21252  %dec.i = add nsw i64 %i, -11253  %gep3 = getelementptr i64, ptr %phi2, i64 -321254  %gep4 = getelementptr i64, ptr %phi1, i64 -321255  %cond = icmp sgt i64 %dec.i, 01256  br i1 %cond, label %for.body, label %end1257end:1258  ret void1259}1260 1261define void @post-indexed-doubleword-offset-out-of-range(ptr %a, ptr %b, i64 %count) nounwind {1262; CHECK-LABEL: post-indexed-doubleword-offset-out-of-range1263; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}]1264; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #2561265; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}]1266; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #2561267 1268  br label %for.body1269for.body:1270  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1271  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1272  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1273  %gep1 = getelementptr i64, ptr %phi1, i64 11274  %load1 = load i64, ptr %gep11275  %gep2 = getelementptr i64, ptr %phi2, i64 11276  store i64 %load1, ptr %gep21277  %load2 = load i64, ptr %phi11278  store i64 %load2, ptr %phi21279  %dec.i = add nsw i64 %i, -11280  %gep3 = getelementptr i64, ptr %phi2, i64 321281  %gep4 = getelementptr i64, ptr %phi1, i64 321282  %cond = icmp sgt i64 %dec.i, 01283  br i1 %cond, label %for.body, label %end1284end:1285  ret void1286}1287 1288define void @post-indexed-paired-min-offset(ptr %a, ptr %b, i64 %count) nounwind {1289; CHECK-LABEL: post-indexed-paired-min-offset1290; CHECK: ldp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}], #-5121291; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}], #-5121292  br label %for.body1293for.body:1294  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1295  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1296  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1297  %gep1 = getelementptr i64, ptr %phi1, i64 11298  %load1 = load i64, ptr %gep11299  %gep2 = getelementptr i64, ptr %phi2, i64 11300  %load2 = load i64, ptr %phi11301  store i64 %load1, ptr %gep21302  store i64 %load2, ptr %phi21303  %dec.i = add nsw i64 %i, -11304  %gep3 = getelementptr i64, ptr %phi2, i64 -641305  %gep4 = getelementptr i64, ptr %phi1, i64 -641306  %cond = icmp sgt i64 %dec.i, 01307  br i1 %cond, label %for.body, label %end1308end:1309  ret void1310}1311 1312define void @post-indexed-paired-offset-out-of-range(ptr %a, ptr %b, i64 %count) nounwind {1313; CHECK-LABEL: post-indexed-paired-offset-out-of-range1314; CHECK: ldp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]1315; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #5121316; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]1317; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #5121318  br label %for.body1319for.body:1320  %phi1 = phi ptr [ %gep4, %for.body ], [ %b, %0 ]1321  %phi2 = phi ptr [ %gep3, %for.body ], [ %a, %0 ]1322  %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]1323  %gep1 = getelementptr i64, ptr %phi1, i64 11324  %load1 = load i64, ptr %phi11325  %gep2 = getelementptr i64, ptr %phi2, i64 11326  %load2 = load i64, ptr %gep11327  store i64 %load1, ptr %gep21328  store i64 %load2, ptr %phi21329  %dec.i = add nsw i64 %i, -11330  %gep3 = getelementptr i64, ptr %phi2, i64 641331  %gep4 = getelementptr i64, ptr %phi1, i64 641332  %cond = icmp sgt i64 %dec.i, 01333  br i1 %cond, label %for.body, label %end1334end:1335  ret void1336}1337 1338; DAGCombiner::MergeConsecutiveStores merges this into a vector store,1339; replaceZeroVectorStore should split the vector store back into1340; scalar stores which should get merged by AArch64LoadStoreOptimizer.1341define void @merge_zr32(ptr %p) {1342; CHECK-LABEL: merge_zr32:1343; CHECK: // %entry1344; NOSTRICTALIGN-NEXT: str xzr, [x{{[0-9]+}}]1345; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1346; CHECK-NEXT: ret1347entry:1348  store i32 0, ptr %p1349  %p1 = getelementptr i32, ptr %p, i32 11350  store i32 0, ptr %p11351  ret void1352}1353 1354; Same as merge_zr32 but the merged stores should also get paried.1355define void @merge_zr32_2(ptr %p) {1356; CHECK-LABEL: merge_zr32_2:1357; CHECK: // %entry1358; NOSTRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1359; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1360; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #8]1361; CHECK-NEXT: ret1362entry:1363  store i32 0, ptr %p1364  %p1 = getelementptr i32, ptr %p, i32 11365  store i32 0, ptr %p11366  %p2 = getelementptr i32, ptr %p, i64 21367  store i32 0, ptr %p21368  %p3 = getelementptr i32, ptr %p, i64 31369  store i32 0, ptr %p31370  ret void1371}1372 1373; Like merge_zr32_2, but checking the largest allowed stp immediate offset.1374define void @merge_zr32_2_offset(ptr %p) {1375; CHECK-LABEL: merge_zr32_2_offset:1376; CHECK: // %entry1377; NOSTRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}, #504]1378; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #504]1379; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #508]1380; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #512]1381; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #516]1382; CHECK-NEXT: ret1383entry:1384  %p0 = getelementptr i32, ptr %p, i32 1261385  store i32 0, ptr %p01386  %p1 = getelementptr i32, ptr %p, i32 1271387  store i32 0, ptr %p11388  %p2 = getelementptr i32, ptr %p, i64 1281389  store i32 0, ptr %p21390  %p3 = getelementptr i32, ptr %p, i64 1291391  store i32 0, ptr %p31392  ret void1393}1394 1395; Like merge_zr32, but replaceZeroVectorStore should not split this1396; vector store since the address offset is too large for the stp1397; instruction.1398define void @no_merge_zr32_2_offset(ptr %p) {1399; CHECK-LABEL: no_merge_zr32_2_offset:1400; CHECK: // %entry1401; NOSTRICTALIGN-NEXT: movi v[[REG:[0-9]]].2d, #00000000000000001402; NOSTRICTALIGN-NEXT: str q[[REG]], [x{{[0-9]+}}, #4096]1403; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #4096]1404; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #4100]1405; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #4104]1406; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #4108]1407; CHECK-NEXT: ret1408entry:1409  %p0 = getelementptr i32, ptr %p, i32 10241410  store i32 0, ptr %p01411  %p1 = getelementptr i32, ptr %p, i32 10251412  store i32 0, ptr %p11413  %p2 = getelementptr i32, ptr %p, i64 10261414  store i32 0, ptr %p21415  %p3 = getelementptr i32, ptr %p, i64 10271416  store i32 0, ptr %p31417  ret void1418}1419 1420; Like merge_zr32, but replaceZeroVectorStore should not split the1421; vector store since the zero constant vector has multiple uses, so we1422; err on the side that allows for stp q instruction generation.1423define void @merge_zr32_3(ptr %p) {1424; CHECK-LABEL: merge_zr32_3:1425; CHECK: // %entry1426; NOSTRICTALIGN-NEXT: movi v[[REG:[0-9]]].2d, #00000000000000001427; NOSTRICTALIGN-NEXT: stp q[[REG]], q[[REG]], [x{{[0-9]+}}]1428; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1429; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #8]1430; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #16]1431; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #24]1432; CHECK-NEXT: ret1433entry:1434  store i32 0, ptr %p1435  %p1 = getelementptr i32, ptr %p, i32 11436  store i32 0, ptr %p11437  %p2 = getelementptr i32, ptr %p, i64 21438  store i32 0, ptr %p21439  %p3 = getelementptr i32, ptr %p, i64 31440  store i32 0, ptr %p31441  %p4 = getelementptr i32, ptr %p, i64 41442  store i32 0, ptr %p41443  %p5 = getelementptr i32, ptr %p, i64 51444  store i32 0, ptr %p51445  %p6 = getelementptr i32, ptr %p, i64 61446  store i32 0, ptr %p61447  %p7 = getelementptr i32, ptr %p, i64 71448  store i32 0, ptr %p71449  ret void1450}1451 1452; Like merge_zr32, but with 2-vector type.1453define void @merge_zr32_2vec(ptr %p) {1454; CHECK-LABEL: merge_zr32_2vec:1455; CHECK: // %entry1456; NOSTRICTALIGN-NEXT: str xzr, [x{{[0-9]+}}]1457; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1458; CHECK-NEXT: ret1459entry:1460  store <2 x i32> zeroinitializer, ptr %p1461  ret void1462}1463 1464; Like merge_zr32, but with 3-vector type.1465define void @merge_zr32_3vec(ptr %p) {1466; CHECK-LABEL: merge_zr32_3vec:1467; CHECK: // %entry1468; NOSTRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}, #8]1469; NOSTRICTALIGN-NEXT: str xzr, [x{{[0-9]+}}]1470; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #4]1471; STRICTALIGN-NEXT: str wzr, [x{{[0-9]+}}]1472; CHECK-NEXT: ret1473entry:1474  store <3 x i32> zeroinitializer, ptr %p1475  ret void1476}1477 1478; Like merge_zr32, but with 4-vector type.1479define void @merge_zr32_4vec(ptr %p) {1480; CHECK-LABEL: merge_zr32_4vec:1481; CHECK: // %entry1482; NOSTRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1483; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #8]1484; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1485; CHECK-NEXT: ret1486entry:1487  store <4 x i32> zeroinitializer, ptr %p1488  ret void1489}1490 1491; Like merge_zr32, but with 2-vector float type.1492define void @merge_zr32_2vecf(ptr %p) {1493; CHECK-LABEL: merge_zr32_2vecf:1494; CHECK: // %entry1495; NOSTRICTALIGN-NEXT: str xzr, [x{{[0-9]+}}]1496; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1497; CHECK-NEXT: ret1498entry:1499  store <2 x float> zeroinitializer, ptr %p1500  ret void1501}1502 1503; Like merge_zr32, but with 4-vector float type.1504define void @merge_zr32_4vecf(ptr %p) {1505; CHECK-LABEL: merge_zr32_4vecf:1506; CHECK: // %entry1507; NOSTRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1508; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}, #8]1509; STRICTALIGN-NEXT: stp wzr, wzr, [x{{[0-9]+}}]1510; CHECK-NEXT: ret1511entry:1512  store <4 x float> zeroinitializer, ptr %p1513  ret void1514}1515 1516; Similar to merge_zr32, but for 64-bit values.1517define void @merge_zr64(ptr %p) {1518; CHECK-LABEL: merge_zr64:1519; CHECK: // %entry1520; CHECK-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1521; CHECK-NEXT: ret1522entry:1523  store i64 0, ptr %p1524  %p1 = getelementptr i64, ptr %p, i64 11525  store i64 0, ptr %p11526  ret void1527}1528 1529; Similar to merge_zr32, but for 64-bit values and with unaligned stores.1530define void @merge_zr64_unalign(ptr %p) {1531; CHECK-LABEL: merge_zr64_unalign:1532; CHECK: // %entry1533; NOSTRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1534; STRICTALIGN: strb1535; STRICTALIGN: strb1536; STRICTALIGN: strb1537; STRICTALIGN: strb1538; STRICTALIGN: strb1539; STRICTALIGN: strb1540; STRICTALIGN: strb1541; STRICTALIGN: strb1542; STRICTALIGN: strb1543; STRICTALIGN: strb1544; STRICTALIGN: strb1545; STRICTALIGN: strb1546; STRICTALIGN: strb1547; STRICTALIGN: strb1548; STRICTALIGN: strb1549; STRICTALIGN: strb1550; CHECK-NEXT: ret1551entry:1552  store <2 x i64> zeroinitializer, ptr %p, align 11553  ret void1554}1555 1556; Similar to merge_zr32_3, replaceZeroVectorStore should not split the1557; vector store since the zero constant vector has multiple uses.1558define void @merge_zr64_2(ptr %p) {1559; CHECK-LABEL: merge_zr64_2:1560; CHECK: // %entry1561; NOSTRICTALIGN-NEXT: movi v[[REG:[0-9]]].2d, #00000000000000001562; NOSTRICTALIGN-NEXT: stp q[[REG]], q[[REG]], [x{{[0-9]+}}]1563; STRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1564; STRICTALIGN-NEXT: stp xzr, xzr, [x{{[0-9]+}}, #16]1565; CHECK-NEXT: ret1566entry:1567  store i64 0, ptr %p1568  %p1 = getelementptr i64, ptr %p, i64 11569  store i64 0, ptr %p11570  %p2 = getelementptr i64, ptr %p, i64 21571  store i64 0, ptr %p21572  %p3 = getelementptr i64, ptr %p, i64 31573  store i64 0, ptr %p31574  ret void1575}1576 1577; Like merge_zr64, but with 2-vector double type.1578define void @merge_zr64_2vecd(ptr %p) {1579; CHECK-LABEL: merge_zr64_2vecd:1580; CHECK: // %entry1581; CHECK-NEXT: stp xzr, xzr, [x{{[0-9]+}}]1582; CHECK-NEXT: ret1583entry:1584  store <2 x double> zeroinitializer, ptr %p1585  ret void1586}1587 1588; Like merge_zr64, but with 3-vector i64 type.1589define void @merge_zr64_3vec(ptr %p) {1590; CHECK-LABEL: merge_zr64_3vec:1591; CHECK: // %entry1592; CHECK-NEXT: stp xzr, xzr, [x{{[0-9]+}}, #8]1593; CHECK-NEXT: str xzr, [x{{[0-9]+}}]1594; CHECK-NEXT: ret1595entry:1596  store <3 x i64> zeroinitializer, ptr %p1597  ret void1598}1599 1600; Like merge_zr64_2, but with 4-vector double type.1601define void @merge_zr64_4vecd(ptr %p) {1602; CHECK-LABEL: merge_zr64_4vecd:1603; CHECK: // %entry1604; CHECK-NEXT: movi v[[REG:[0-9]]].2d, #00000000000000001605; CHECK-NEXT: stp q[[REG]], q[[REG]], [x{{[0-9]+}}]1606; CHECK-NEXT: ret1607entry:1608  store <4 x double> zeroinitializer, ptr %p1609  ret void1610}1611 1612; Verify that non-consecutive merges do not generate q01613define void @merge_multiple_128bit_stores(ptr %p) {1614; CHECK-LABEL: merge_multiple_128bit_stores1615; CHECK: // %entry1616; NOSTRICTALIGN-NEXT: movi v[[REG:[0-9]]].2d, #00000000000000001617; NOSTRICTALIGN-NEXT: str q0, [x0]1618; NOSTRICTALIGN-NEXT: stur q0, [x0, #24]1619; NOSTRICTALIGN-NEXT: str q0, [x0, #48]1620; STRICTALIGN-NEXT: stp xzr, xzr, [x0]1621; STRICTALIGN-NEXT: stp xzr, xzr, [x0, #24]1622; STRICTALIGN-NEXT: stp xzr, xzr, [x0, #48]1623; CHECK-NEXT: ret1624entry:1625  store i64 0, ptr %p1626  %p1 = getelementptr i64, ptr %p, i64 11627  store i64 0, ptr %p11628  %p3 = getelementptr i64, ptr %p, i64 31629  store i64 0, ptr %p31630  %p4 = getelementptr i64, ptr %p, i64 41631  store i64 0, ptr %p41632  %p6 = getelementptr i64, ptr %p, i64 61633  store i64 0, ptr %p61634  %p7 = getelementptr i64, ptr %p, i64 71635  store i64 0, ptr %p71636  ret void1637}1638 1639; Verify that large stores generate stp q1640define void @merge_multiple_128bit_stores_consec(ptr %p) {1641; CHECK-LABEL: merge_multiple_128bit_stores_consec1642; CHECK: // %entry1643; NOSTRICTALIGN-NEXT: movi v[[REG:[0-9]]].2d, #00000000000000001644; NOSTRICTALIGN-NEXT: stp q[[REG]], q[[REG]], [x{{[0-9]+}}]1645; NOSTRICTALIGN-NEXT: stp q[[REG]], q[[REG]], [x{{[0-9]+}}, #32]1646; STRICTALIGN-NEXT: stp	 xzr, xzr, [x0]1647; STRICTALIGN-NEXT: stp	 xzr, xzr, [x0, #16]1648; STRICTALIGN-NEXT: stp	 xzr, xzr, [x0, #32]1649; STRICTALIGN-NEXT: stp  xzr, xzr, [x0, #48]1650; CHECK-NEXT: ret1651entry:1652  store i64 0, ptr %p1653  %p1 = getelementptr i64, ptr %p, i64 11654  store i64 0, ptr %p11655  %p2 = getelementptr i64, ptr %p, i64 21656  store i64 0, ptr %p21657  %p3 = getelementptr i64, ptr %p, i64 31658  store i64 0, ptr %p31659  %p4 = getelementptr i64, ptr %p, i64 41660  store i64 0, ptr %p41661  %p5 = getelementptr i64, ptr %p, i64 51662  store i64 0, ptr %p51663  %p6 = getelementptr i64, ptr %p, i64 61664  store i64 0, ptr %p61665  %p7 = getelementptr i64, ptr %p, i64 71666  store i64 0, ptr %p71667  ret void1668}1669 1670; Check for bug 34674 where invalid add of xzr was being generated.1671; CHECK-LABEL: bug34674:1672; CHECK: // %entry1673; CHECK-NEXT: mov [[ZREG:x[0-9]+]], xzr1674; CHECK-NEXT: mov x8, x01675; CHECK-NEXT: add x0, [[ZREG]], #11676; CHECK-NEXT: stp xzr, xzr, [x8]1677define i64 @bug34674(ptr %p) {1678entry:1679  store <2 x i64> zeroinitializer, ptr %p1680  %ld = load i64, ptr %p1681  %add = add i64 %ld, 11682  ret i64 %add1683}1684 1685; CHECK-LABEL: trunc_splat_zero:1686; CHECK-DAG: strh wzr, [x0]1687define void @trunc_splat_zero(ptr %ptr) {1688  store <2 x i8> zeroinitializer, ptr %ptr, align 21689  ret void1690}1691 1692; CHECK-LABEL: trunc_splat:1693; CHECK: mov [[VAL:w[0-9]+]], #421694; CHECK: movk [[VAL]], #42, lsl #161695; CHECK: str [[VAL]], [x0]1696define void @trunc_splat(ptr %ptr) {1697  store <2 x i16> <i16 42, i16 42>, ptr %ptr, align 41698  ret void1699}1700