322 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s3 4; Scalar tests.5 6; add (add %x, C), %y7; 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, w113; CHECK-NEXT: add w0, w8, #3214; CHECK-NEXT: ret15 %t0 = add i32 %a, 32 ; constant always on RHS16 %r = add i32 %t0, %b17 ret i32 %r18}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, w123; CHECK-NEXT: add w0, w8, #3224; CHECK-NEXT: ret25 %t0 = add i32 %a, 32 ; constant always on RHS26 %r = add i32 %b, %t027 ret i32 %r28}29 30; add (sub %x, C), %y31; 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, w137; CHECK-NEXT: sub w0, w8, #3238; CHECK-NEXT: ret39 %t0 = sub i32 %a, 3240 %r = add i32 %t0, %b41 ret i32 %r42}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, w147; CHECK-NEXT: sub w0, w8, #3248; CHECK-NEXT: ret49 %t0 = sub i32 %a, 3250 %r = add i32 %b, %t051 ret i32 %r52}53 54; add (sub C, %x), %y55; 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, w061; CHECK-NEXT: add w0, w8, #3262; CHECK-NEXT: ret63 %t0 = sub i32 32, %a64 %r = add i32 %t0, %b65 ret i32 %r66}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, w071; CHECK-NEXT: add w0, w8, #3272; CHECK-NEXT: ret73 %t0 = sub i32 32, %a74 %r = add i32 %b, %t075 ret i32 %r76}77 78; sub (add %x, C), %y79; 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, w185; CHECK-NEXT: add w0, w8, #3286; CHECK-NEXT: ret87 %t0 = add i32 %a, 32 ; constant always on RHS88 %r = sub i32 %t0, %b89 ret i32 %r90}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, w095; CHECK-NEXT: sub w0, w8, #3296; CHECK-NEXT: ret97 %t0 = add i32 %a, 32 ; constant always on RHS98 %r = sub i32 %b, %t099 ret i32 %r100}101 102; sub (sub %x, C), %y103; 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, w1109; CHECK-NEXT: sub w0, w8, #32110; CHECK-NEXT: ret111 %t0 = sub i32 %a, 32112 %r = sub i32 %t0, %b113 ret i32 %r114}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, w0119; CHECK-NEXT: add w0, w8, #32120; CHECK-NEXT: ret121 %t0 = sub i32 %a, 32122 %r = sub i32 %b, %t0123 ret i32 %r124}125 126; sub (sub C, %x), %y127; 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 // =0x20133; CHECK-NEXT: add w9, w0, w1134; CHECK-NEXT: sub w0, w8, w9135; CHECK-NEXT: ret136 %t0 = sub i32 32, %a137 %r = sub i32 %t0, %b138 ret i32 %r139}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, w1144; CHECK-NEXT: sub w0, w8, #32145; CHECK-NEXT: ret146 %t0 = sub i32 32, %a147 %r = sub i32 %b, %t0148 ret i32 %r149}150 151;------------------------------------------------------------------------------;152; Basic vector tests. Here it is easier to see where the constant operand is.153;------------------------------------------------------------------------------;154 155; add (add %x, C), %y156; 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_0162; CHECK-NEXT: add v0.4s, v0.4s, v1.4s163; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI12_0]164; CHECK-NEXT: add v0.4s, v0.4s, v1.4s165; CHECK-NEXT: ret166 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS167 %r = add <4 x i32> %t0, %b168 ret <4 x i32> %r169}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_0174; CHECK-NEXT: add v0.4s, v0.4s, v1.4s175; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI13_0]176; CHECK-NEXT: add v0.4s, v0.4s, v1.4s177; CHECK-NEXT: ret178 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS179 %r = add <4 x i32> %b, %t0180 ret <4 x i32> %r181}182 183; add (sub %x, C), %y184; 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_0190; CHECK-NEXT: add v0.4s, v0.4s, v1.4s191; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI14_0]192; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s193; CHECK-NEXT: ret194 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>195 %r = add <4 x i32> %t0, %b196 ret <4 x i32> %r197}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_0202; CHECK-NEXT: add v0.4s, v0.4s, v1.4s203; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI15_0]204; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s205; CHECK-NEXT: ret206 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>207 %r = add <4 x i32> %b, %t0208 ret <4 x i32> %r209}210 211; add (sub C, %x), %y212; 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_0218; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s219; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI16_0]220; CHECK-NEXT: add v0.4s, v0.4s, v1.4s221; CHECK-NEXT: ret222 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a223 %r = add <4 x i32> %t0, %b224 ret <4 x i32> %r225}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_0230; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s231; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI17_0]232; CHECK-NEXT: add v0.4s, v0.4s, v1.4s233; CHECK-NEXT: ret234 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a235 %r = add <4 x i32> %b, %t0236 ret <4 x i32> %r237}238 239; sub (add %x, C), %y240; 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_0246; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s247; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI18_0]248; CHECK-NEXT: add v0.4s, v0.4s, v1.4s249; CHECK-NEXT: ret250 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS251 %r = sub <4 x i32> %t0, %b252 ret <4 x i32> %r253}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_0258; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s259; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI19_0]260; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s261; CHECK-NEXT: ret262 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS263 %r = sub <4 x i32> %b, %t0264 ret <4 x i32> %r265}266 267; sub (sub %x, C), %y268; 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_0274; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s275; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI20_0]276; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s277; CHECK-NEXT: ret278 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>279 %r = sub <4 x i32> %t0, %b280 ret <4 x i32> %r281}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_0286; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s287; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI21_0]288; CHECK-NEXT: add v0.4s, v0.4s, v1.4s289; CHECK-NEXT: ret290 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>291 %r = sub <4 x i32> %b, %t0292 ret <4 x i32> %r293}294 295; sub (sub C, %x), %y296; 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_0302; CHECK-NEXT: add v0.4s, v0.4s, v1.4s303; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI22_0]304; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s305; CHECK-NEXT: ret306 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a307 %r = sub <4 x i32> %t0, %b308 ret <4 x i32> %r309}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_0314; CHECK-NEXT: add v0.4s, v0.4s, v1.4s315; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI23_0]316; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s317; CHECK-NEXT: ret318 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a319 %r = sub <4 x i32> %b, %t0320 ret <4 x i32> %r321}322