[AArch64] Fix crash with empty/pseudo-only blocks in A53 erratum (835769) workaround
[oota-llvm.git] / test / CodeGen / AArch64 / fast-isel-addressing-modes.ll
index e562a5dba05e5c743cadfa7d1825844551c9900b..b5144abe9f333f8f9367e3a11bd6084e9a889d75 100644 (file)
@@ -172,9 +172,12 @@ define i32 @load_breg_immoff_5(i64 %a) {
 
 ; Min un-supported scaled offset
 define i32 @load_breg_immoff_6(i64 %a) {
-; CHECK-LABEL: load_breg_immoff_6
-; CHECK:       add [[REG:x[0-9]+]], x0, #4, lsl #12
-; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
+; SDAG-LABEL: load_breg_immoff_6
+; SDAG:       orr      w[[NUM:[0-9]+]], wzr, #0x4000
+; SDAG-NEXT:  ldr {{w[0-9]+}}, [x0, x[[NUM]]]
+; FAST-LABEL: load_breg_immoff_6
+; FAST:       add [[REG:x[0-9]+]], x0, #4, lsl #12
+; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
   %1 = add i64 %a, 16384
   %2 = inttoptr i64 %1 to i32*
   %3 = load i32* %2
@@ -235,9 +238,12 @@ define void @store_breg_immoff_5(i64 %a) {
 
 ; Min un-supported scaled offset
 define void @store_breg_immoff_6(i64 %a) {
-; CHECK-LABEL: store_breg_immoff_6
-; CHECK:       add [[REG:x[0-9]+]], x0, #4, lsl #12
-; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
+; SDAG-LABEL: store_breg_immoff_6
+; SDAG:       orr      w[[NUM:[0-9]+]], wzr, #0x4000
+; SDAG-NEXT:  str wzr, [x0, x[[NUM]]]
+; FAST-LABEL: store_breg_immoff_6
+; FAST:       add [[REG:x[0-9]+]], x0, #4, lsl #12
+; FAST-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
   %1 = add i64 %a, 16384
   %2 = inttoptr i64 %1 to i32*
   store i32 0, i32* %2
@@ -298,8 +304,8 @@ define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
 define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
 ; SDAG-LABEL: load_breg_offreg_immoff_2
 ; SDAG:       add [[REG1:x[0-9]+]], x0, x1
-; SDAG-NEXT:  add [[REG2:x[0-9]+]], [[REG1]], #15, lsl #12
-; SDAG-NEXT:  ldr x0, {{\[}}[[REG2]]{{\]}}
+; SDAG-NEXT:  orr w[[NUM:[0-9]+]], wzr, #0xf000
+; SDAG-NEXT:  ldr x0, {{\[}}[[REG1]], x[[NUM]]]
 ; FAST-LABEL: load_breg_offreg_immoff_2
 ; FAST:       add [[REG:x[0-9]+]], x0, #15, lsl #12
 ; FAST-NEXT:  ldr x0, {{\[}}[[REG]], x1{{\]}}
@@ -450,6 +456,30 @@ define i64 @load_breg_and_offreg_4(i64 %a, i64 %b) {
   ret i64 %5
 }
 
+; Not all 'and' instructions have immediates.
+define i64 @load_breg_and_offreg_5(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: load_breg_and_offreg_5
+; CHECK:       and [[REG:x[0-9]+]], x0, x2
+; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], x1{{\]}}
+  %1 = and i64 %a, %c
+  %2 = add i64 %1, %b
+  %3 = inttoptr i64 %2 to i64*
+  %4 = load i64* %3
+  ret i64 %4
+}
+
+define i64 @load_breg_and_offreg_6(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: load_breg_and_offreg_6
+; CHECK:       and [[REG:x[0-9]+]], x0, x2
+; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}x1, [[REG]], lsl #3{{\]}}
+  %1 = and i64 %a, %c
+  %2 = shl i64 %1, 3
+  %3 = add i64 %2, %b
+  %4 = inttoptr i64 %3 to i64*
+  %5 = load i64* %4
+  ret i64 %5
+}
+
 ; Load Base Register + Scaled Register Offset + Sign/Zero extension
 define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
 ; CHECK-LABEL: load_breg_zext_shift_offreg_1
@@ -506,6 +536,21 @@ define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
   ret i32 %5
 }
 
+; Make sure that we don't drop the first 'add' instruction.
+define i32 @load_breg_sext_shift_offreg_3(i32 %a, i64 %b) {
+; CHECK-LABEL: load_breg_sext_shift_offreg_3
+; CHECK:       add [[REG:w[0-9]+]], w0, #4
+; CHECK:       ldr {{w[0-9]+}}, {{\[}}x1, [[REG]], sxtw #2{{\]}}
+  %1 = add i32 %a, 4
+  %2 = sext i32 %1 to i64
+  %3 = shl i64 %2, 2
+  %4 = add i64 %b, %3
+  %5 = inttoptr i64 %4 to i32*
+  %6 = load i32* %5
+  ret i32 %6
+}
+
+
 define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) {
 ; CHECK-LABEL: load_breg_sext_mul_offreg_1
 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]