1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s 3 4; Scalar tests. 5 6; add (add %x, C), %y 7; Outer 'add' is commutative - 2 variants. 8 9define i32 @sink_add_of_const_to_add0(i32 %a, i32 %b) { 10; CHECK-LABEL: sink_add_of_const_to_add0: 11; CHECK: // %bb.0: 12; CHECK-NEXT: add w8, w0, w1 13; CHECK-NEXT: add w0, w8, #32 14; CHECK-NEXT: ret 15 %t0 = add i32 %a, 32 ; constant always on RHS 16 %r = add i32 %t0, %b 17 ret i32 %r 18} 19define i32 @sink_add_of_const_to_add1(i32 %a, i32 %b) { 20; CHECK-LABEL: sink_add_of_const_to_add1: 21; CHECK: // %bb.0: 22; CHECK-NEXT: add w8, w0, w1 23; CHECK-NEXT: add w0, w8, #32 24; CHECK-NEXT: ret 25 %t0 = add i32 %a, 32 ; constant always on RHS 26 %r = add i32 %b, %t0 27 ret i32 %r 28} 29 30; add (sub %x, C), %y 31; Outer 'add' is commutative - 2 variants. 32 33define i32 @sink_sub_of_const_to_add0(i32 %a, i32 %b) { 34; CHECK-LABEL: sink_sub_of_const_to_add0: 35; CHECK: // %bb.0: 36; CHECK-NEXT: add w8, w0, w1 37; CHECK-NEXT: sub w0, w8, #32 38; CHECK-NEXT: ret 39 %t0 = sub i32 %a, 32 40 %r = add i32 %t0, %b 41 ret i32 %r 42} 43define i32 @sink_sub_of_const_to_add1(i32 %a, i32 %b) { 44; CHECK-LABEL: sink_sub_of_const_to_add1: 45; CHECK: // %bb.0: 46; CHECK-NEXT: add w8, w0, w1 47; CHECK-NEXT: sub w0, w8, #32 48; CHECK-NEXT: ret 49 %t0 = sub i32 %a, 32 50 %r = add i32 %b, %t0 51 ret i32 %r 52} 53 54; add (sub C, %x), %y 55; Outer 'add' is commutative - 2 variants. 56 57define i32 @sink_sub_from_const_to_add0(i32 %a, i32 %b) { 58; CHECK-LABEL: sink_sub_from_const_to_add0: 59; CHECK: // %bb.0: 60; CHECK-NEXT: sub w8, w1, w0 61; CHECK-NEXT: add w0, w8, #32 62; CHECK-NEXT: ret 63 %t0 = sub i32 32, %a 64 %r = add i32 %t0, %b 65 ret i32 %r 66} 67define i32 @sink_sub_from_const_to_add1(i32 %a, i32 %b) { 68; CHECK-LABEL: sink_sub_from_const_to_add1: 69; CHECK: // %bb.0: 70; CHECK-NEXT: sub w8, w1, w0 71; CHECK-NEXT: add w0, w8, #32 72; CHECK-NEXT: ret 73 %t0 = sub i32 32, %a 74 %r = add i32 %b, %t0 75 ret i32 %r 76} 77 78; sub (add %x, C), %y 79; sub %y, (add %x, C) 80 81define i32 @sink_add_of_const_to_sub(i32 %a, i32 %b) { 82; CHECK-LABEL: sink_add_of_const_to_sub: 83; CHECK: // %bb.0: 84; CHECK-NEXT: sub w8, w0, w1 85; CHECK-NEXT: add w0, w8, #32 86; CHECK-NEXT: ret 87 %t0 = add i32 %a, 32 ; constant always on RHS 88 %r = sub i32 %t0, %b 89 ret i32 %r 90} 91define i32 @sink_add_of_const_to_sub2(i32 %a, i32 %b) { 92; CHECK-LABEL: sink_add_of_const_to_sub2: 93; CHECK: // %bb.0: 94; CHECK-NEXT: sub w8, w1, w0 95; CHECK-NEXT: sub w0, w8, #32 96; CHECK-NEXT: ret 97 %t0 = add i32 %a, 32 ; constant always on RHS 98 %r = sub i32 %b, %t0 99 ret i32 %r 100} 101 102; sub (sub %x, C), %y 103; sub %y, (sub %x, C) 104 105define i32 @sink_sub_of_const_to_sub(i32 %a, i32 %b) { 106; CHECK-LABEL: sink_sub_of_const_to_sub: 107; CHECK: // %bb.0: 108; CHECK-NEXT: sub w8, w0, w1 109; CHECK-NEXT: sub w0, w8, #32 110; CHECK-NEXT: ret 111 %t0 = sub i32 %a, 32 112 %r = sub i32 %t0, %b 113 ret i32 %r 114} 115define i32 @sink_sub_of_const_to_sub2(i32 %a, i32 %b) { 116; CHECK-LABEL: sink_sub_of_const_to_sub2: 117; CHECK: // %bb.0: 118; CHECK-NEXT: sub w8, w1, w0 119; CHECK-NEXT: add w0, w8, #32 120; CHECK-NEXT: ret 121 %t0 = sub i32 %a, 32 122 %r = sub i32 %b, %t0 123 ret i32 %r 124} 125 126; sub (sub C, %x), %y 127; sub %y, (sub C, %x) 128 129define i32 @sink_sub_from_const_to_sub(i32 %a, i32 %b) { 130; CHECK-LABEL: sink_sub_from_const_to_sub: 131; CHECK: // %bb.0: 132; CHECK-NEXT: mov w8, #32 // =0x20 133; CHECK-NEXT: add w9, w0, w1 134; CHECK-NEXT: sub w0, w8, w9 135; CHECK-NEXT: ret 136 %t0 = sub i32 32, %a 137 %r = sub i32 %t0, %b 138 ret i32 %r 139} 140define i32 @sink_sub_from_const_to_sub2(i32 %a, i32 %b) { 141; CHECK-LABEL: sink_sub_from_const_to_sub2: 142; CHECK: // %bb.0: 143; CHECK-NEXT: add w8, w0, w1 144; CHECK-NEXT: sub w0, w8, #32 145; CHECK-NEXT: ret 146 %t0 = sub i32 32, %a 147 %r = sub i32 %b, %t0 148 ret i32 %r 149} 150 151;------------------------------------------------------------------------------; 152; Basic vector tests. Here it is easier to see where the constant operand is. 153;------------------------------------------------------------------------------; 154 155; add (add %x, C), %y 156; Outer 'add' is commutative - 2 variants. 157 158define <4 x i32> @vec_sink_add_of_const_to_add0(<4 x i32> %a, <4 x i32> %b) { 159; CHECK-LABEL: vec_sink_add_of_const_to_add0: 160; CHECK: // %bb.0: 161; CHECK-NEXT: adrp x8, .LCPI12_0 162; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 163; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI12_0] 164; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 165; CHECK-NEXT: ret 166 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS 167 %r = add <4 x i32> %t0, %b 168 ret <4 x i32> %r 169} 170define <4 x i32> @vec_sink_add_of_const_to_add1(<4 x i32> %a, <4 x i32> %b) { 171; CHECK-LABEL: vec_sink_add_of_const_to_add1: 172; CHECK: // %bb.0: 173; CHECK-NEXT: adrp x8, .LCPI13_0 174; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 175; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI13_0] 176; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 177; CHECK-NEXT: ret 178 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS 179 %r = add <4 x i32> %b, %t0 180 ret <4 x i32> %r 181} 182 183; add (sub %x, C), %y 184; Outer 'add' is commutative - 2 variants. 185 186define <4 x i32> @vec_sink_sub_of_const_to_add0(<4 x i32> %a, <4 x i32> %b) { 187; CHECK-LABEL: vec_sink_sub_of_const_to_add0: 188; CHECK: // %bb.0: 189; CHECK-NEXT: adrp x8, .LCPI14_0 190; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 191; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI14_0] 192; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 193; CHECK-NEXT: ret 194 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> 195 %r = add <4 x i32> %t0, %b 196 ret <4 x i32> %r 197} 198define <4 x i32> @vec_sink_sub_of_const_to_add1(<4 x i32> %a, <4 x i32> %b) { 199; CHECK-LABEL: vec_sink_sub_of_const_to_add1: 200; CHECK: // %bb.0: 201; CHECK-NEXT: adrp x8, .LCPI15_0 202; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 203; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI15_0] 204; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 205; CHECK-NEXT: ret 206 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> 207 %r = add <4 x i32> %b, %t0 208 ret <4 x i32> %r 209} 210 211; add (sub C, %x), %y 212; Outer 'add' is commutative - 2 variants. 213 214define <4 x i32> @vec_sink_sub_from_const_to_add0(<4 x i32> %a, <4 x i32> %b) { 215; CHECK-LABEL: vec_sink_sub_from_const_to_add0: 216; CHECK: // %bb.0: 217; CHECK-NEXT: adrp x8, .LCPI16_0 218; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 219; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI16_0] 220; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 221; CHECK-NEXT: ret 222 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a 223 %r = add <4 x i32> %t0, %b 224 ret <4 x i32> %r 225} 226define <4 x i32> @vec_sink_sub_from_const_to_add1(<4 x i32> %a, <4 x i32> %b) { 227; CHECK-LABEL: vec_sink_sub_from_const_to_add1: 228; CHECK: // %bb.0: 229; CHECK-NEXT: adrp x8, .LCPI17_0 230; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 231; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI17_0] 232; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 233; CHECK-NEXT: ret 234 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a 235 %r = add <4 x i32> %b, %t0 236 ret <4 x i32> %r 237} 238 239; sub (add %x, C), %y 240; sub %y, (add %x, C) 241 242define <4 x i32> @vec_sink_add_of_const_to_sub(<4 x i32> %a, <4 x i32> %b) { 243; CHECK-LABEL: vec_sink_add_of_const_to_sub: 244; CHECK: // %bb.0: 245; CHECK-NEXT: adrp x8, .LCPI18_0 246; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 247; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI18_0] 248; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 249; CHECK-NEXT: ret 250 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS 251 %r = sub <4 x i32> %t0, %b 252 ret <4 x i32> %r 253} 254define <4 x i32> @vec_sink_add_of_const_to_sub2(<4 x i32> %a, <4 x i32> %b) { 255; CHECK-LABEL: vec_sink_add_of_const_to_sub2: 256; CHECK: // %bb.0: 257; CHECK-NEXT: adrp x8, .LCPI19_0 258; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 259; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI19_0] 260; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 261; CHECK-NEXT: ret 262 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS 263 %r = sub <4 x i32> %b, %t0 264 ret <4 x i32> %r 265} 266 267; sub (sub %x, C), %y 268; sub %y, (sub %x, C) 269 270define <4 x i32> @vec_sink_sub_of_const_to_sub(<4 x i32> %a, <4 x i32> %b) { 271; CHECK-LABEL: vec_sink_sub_of_const_to_sub: 272; CHECK: // %bb.0: 273; CHECK-NEXT: adrp x8, .LCPI20_0 274; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 275; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI20_0] 276; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 277; CHECK-NEXT: ret 278 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> 279 %r = sub <4 x i32> %t0, %b 280 ret <4 x i32> %r 281} 282define <4 x i32> @vec_sink_sub_of_const_to_sub2(<4 x i32> %a, <4 x i32> %b) { 283; CHECK-LABEL: vec_sink_sub_of_const_to_sub2: 284; CHECK: // %bb.0: 285; CHECK-NEXT: adrp x8, .LCPI21_0 286; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 287; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI21_0] 288; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 289; CHECK-NEXT: ret 290 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> 291 %r = sub <4 x i32> %b, %t0 292 ret <4 x i32> %r 293} 294 295; sub (sub C, %x), %y 296; sub %y, (sub C, %x) 297 298define <4 x i32> @vec_sink_sub_from_const_to_sub(<4 x i32> %a, <4 x i32> %b) { 299; CHECK-LABEL: vec_sink_sub_from_const_to_sub: 300; CHECK: // %bb.0: 301; CHECK-NEXT: adrp x8, .LCPI22_0 302; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 303; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI22_0] 304; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 305; CHECK-NEXT: ret 306 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a 307 %r = sub <4 x i32> %t0, %b 308 ret <4 x i32> %r 309} 310define <4 x i32> @vec_sink_sub_from_const_to_sub2(<4 x i32> %a, <4 x i32> %b) { 311; CHECK-LABEL: vec_sink_sub_from_const_to_sub2: 312; CHECK: // %bb.0: 313; CHECK-NEXT: adrp x8, .LCPI23_0 314; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 315; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI23_0] 316; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 317; CHECK-NEXT: ret 318 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a 319 %r = sub <4 x i32> %b, %t0 320 ret <4 x i32> %r 321} 322