271 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=371045 6; X: [byte3] [byte0]7; Y: [byte2][byte1]8 9define i8 @out8_constmask(i8 %x, i8 %y) {10; CHECK-LABEL: out8_constmask:11; CHECK: // %bb.0:12; CHECK-NEXT: lsr w8, w0, #213; CHECK-NEXT: mov w0, w114; CHECK-NEXT: bfi w0, w8, #2, #415; CHECK-NEXT: ret16 %mx = and i8 %x, 6017 %my = and i8 %y, -6118 %r = or i8 %mx, %my19 ret i8 %r20}21 22define i16 @out16_constmask(i16 %x, i16 %y) {23; CHECK-LABEL: out16_constmask:24; CHECK: // %bb.0:25; CHECK-NEXT: lsr w8, w0, #426; CHECK-NEXT: mov w0, w127; CHECK-NEXT: bfi w0, w8, #4, #828; CHECK-NEXT: ret29 %mx = and i16 %x, 408030 %my = and i16 %y, -408131 %r = or i16 %mx, %my32 ret i16 %r33}34 35define i32 @out32_constmask(i32 %x, i32 %y) {36; CHECK-LABEL: out32_constmask:37; CHECK: // %bb.0:38; CHECK-NEXT: lsr w8, w0, #839; CHECK-NEXT: mov w0, w140; CHECK-NEXT: bfi w0, w8, #8, #1641; CHECK-NEXT: ret42 %mx = and i32 %x, 1677696043 %my = and i32 %y, -1677696144 %r = or i32 %mx, %my45 ret i32 %r46}47 48define i64 @out64_constmask(i64 %x, i64 %y) {49; CHECK-LABEL: out64_constmask:50; CHECK: // %bb.0:51; CHECK-NEXT: lsr x8, x0, #1652; CHECK-NEXT: mov x0, x153; CHECK-NEXT: bfi x0, x8, #16, #3254; CHECK-NEXT: ret55 %mx = and i64 %x, 28147497664512056 %my = and i64 %y, -28147497664512157 %r = or i64 %mx, %my58 ret i64 %r59}60 61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62; Should be the same as the previous one.63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64 65define i8 @in8_constmask(i8 %x, i8 %y) {66; CHECK-LABEL: in8_constmask:67; CHECK: // %bb.0:68; CHECK-NEXT: eor w8, w0, w169; CHECK-NEXT: and w8, w8, #0x3c70; CHECK-NEXT: eor w0, w8, w171; CHECK-NEXT: ret72 %n0 = xor i8 %x, %y73 %n1 = and i8 %n0, 6074 %r = xor i8 %n1, %y75 ret i8 %r76}77 78define i16 @in16_constmask(i16 %x, i16 %y) {79; CHECK-LABEL: in16_constmask:80; CHECK: // %bb.0:81; CHECK-NEXT: eor w8, w0, w182; CHECK-NEXT: and w8, w8, #0xff083; CHECK-NEXT: eor w0, w8, w184; CHECK-NEXT: ret85 %n0 = xor i16 %x, %y86 %n1 = and i16 %n0, 408087 %r = xor i16 %n1, %y88 ret i16 %r89}90 91define i32 @in32_constmask(i32 %x, i32 %y) {92; CHECK-LABEL: in32_constmask:93; CHECK: // %bb.0:94; CHECK-NEXT: eor w8, w0, w195; CHECK-NEXT: and w8, w8, #0xffff0096; CHECK-NEXT: eor w0, w8, w197; CHECK-NEXT: ret98 %n0 = xor i32 %x, %y99 %n1 = and i32 %n0, 16776960100 %r = xor i32 %n1, %y101 ret i32 %r102}103 104define i64 @in64_constmask(i64 %x, i64 %y) {105; CHECK-LABEL: in64_constmask:106; CHECK: // %bb.0:107; CHECK-NEXT: eor x8, x0, x1108; CHECK-NEXT: and x8, x8, #0xffffffff0000109; CHECK-NEXT: eor x0, x8, x1110; CHECK-NEXT: ret111 %n0 = xor i64 %x, %y112 %n1 = and i64 %n0, 281474976645120113 %r = xor i64 %n1, %y114 ret i64 %r115}116 117; ============================================================================ ;118; Constant Commutativity tests.119; ============================================================================ ;120 121define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {122; CHECK-LABEL: in_constmask_commutativity_0_1:123; CHECK: // %bb.0:124; CHECK-NEXT: eor w8, w0, w1125; CHECK-NEXT: and w8, w8, #0xffff00126; CHECK-NEXT: eor w0, w1, w8127; CHECK-NEXT: ret128 %n0 = xor i32 %x, %y129 %n1 = and i32 %n0, 16776960130 %r = xor i32 %y, %n1 ; swapped131 ret i32 %r132}133 134define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {135; CHECK-LABEL: in_constmask_commutativity_1_0:136; CHECK: // %bb.0:137; CHECK-NEXT: eor w8, w0, w1138; CHECK-NEXT: and w8, w8, #0xffff00139; CHECK-NEXT: eor w0, w8, w0140; CHECK-NEXT: ret141 %n0 = xor i32 %x, %y142 %n1 = and i32 %n0, 16776960143 %r = xor i32 %n1, %x ; %x instead of %y144 ret i32 %r145}146 147define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {148; CHECK-LABEL: in_constmask_commutativity_1_1:149; CHECK: // %bb.0:150; CHECK-NEXT: eor w8, w0, w1151; CHECK-NEXT: and w8, w8, #0xffff00152; CHECK-NEXT: eor w0, w0, w8153; CHECK-NEXT: ret154 %n0 = xor i32 %x, %y155 %n1 = and i32 %n0, 16776960156 %r = xor i32 %x, %n1 ; swapped, %x instead of %y157 ret i32 %r158}159 160; ============================================================================ ;161; Y is an 'and' too.162; ============================================================================ ;163 164define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {165; CHECK-LABEL: in_complex_y0_constmask:166; CHECK: // %bb.0:167; CHECK-NEXT: and w8, w1, w2168; CHECK-NEXT: eor w9, w0, w8169; CHECK-NEXT: and w9, w9, #0xffff00170; CHECK-NEXT: eor w0, w9, w8171; CHECK-NEXT: ret172 %y = and i32 %y_hi, %y_low173 %n0 = xor i32 %x, %y174 %n1 = and i32 %n0, 16776960175 %r = xor i32 %n1, %y176 ret i32 %r177}178 179define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {180; CHECK-LABEL: in_complex_y1_constmask:181; CHECK: // %bb.0:182; CHECK-NEXT: and w8, w1, w2183; CHECK-NEXT: eor w9, w0, w8184; CHECK-NEXT: and w9, w9, #0xffff00185; CHECK-NEXT: eor w0, w8, w9186; CHECK-NEXT: ret187 %y = and i32 %y_hi, %y_low188 %n0 = xor i32 %x, %y189 %n1 = and i32 %n0, 16776960190 %r = xor i32 %y, %n1191 ret i32 %r192}193 194; ============================================================================ ;195; Negative tests. Should not be folded.196; ============================================================================ ;197 198; Multi-use tests.199 200declare void @use32(i32) nounwind201 202define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {203; CHECK-LABEL: in_multiuse_A_constmask:204; CHECK: // %bb.0:205; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill206; CHECK-NEXT: eor w8, w0, w1207; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill208; CHECK-NEXT: mov w19, w1209; CHECK-NEXT: and w20, w8, #0xffff00210; CHECK-NEXT: mov w0, w20211; CHECK-NEXT: bl use32212; CHECK-NEXT: eor w0, w20, w19213; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload214; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload215; CHECK-NEXT: ret216 %n0 = xor i32 %x, %y217 %n1 = and i32 %n0, 16776960218 call void @use32(i32 %n1)219 %r = xor i32 %n1, %y220 ret i32 %r221}222 223define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {224; CHECK-LABEL: in_multiuse_B_constmask:225; CHECK: // %bb.0:226; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill227; CHECK-NEXT: eor w0, w0, w1228; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill229; CHECK-NEXT: mov w19, w1230; CHECK-NEXT: and w20, w0, #0xffff00231; CHECK-NEXT: bl use32232; CHECK-NEXT: eor w0, w20, w19233; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload234; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload235; CHECK-NEXT: ret236 %n0 = xor i32 %x, %y237 %n1 = and i32 %n0, 16776960238 call void @use32(i32 %n0)239 %r = xor i32 %n1, %y240 ret i32 %r241}242 243; Various bad variants244 245define i32 @n0_badconstmask(i32 %x, i32 %y) {246; CHECK-LABEL: n0_badconstmask:247; CHECK: // %bb.0:248; CHECK-NEXT: and w8, w1, #0xffffff00249; CHECK-NEXT: and w9, w0, #0xffff00250; CHECK-NEXT: and w8, w8, #0xff0001ff251; CHECK-NEXT: orr w0, w9, w8252; CHECK-NEXT: ret253 %mx = and i32 %x, 16776960254 %my = and i32 %y, -16776960 ; instead of -16776961255 %r = or i32 %mx, %my256 ret i32 %r257}258 259define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {260; CHECK-LABEL: n1_thirdvar_constmask:261; CHECK: // %bb.0:262; CHECK-NEXT: eor w8, w0, w1263; CHECK-NEXT: and w8, w8, #0xffff00264; CHECK-NEXT: eor w0, w8, w2265; CHECK-NEXT: ret266 %n0 = xor i32 %x, %y267 %n1 = and i32 %n0, 16776960268 %r = xor i32 %n1, %z ; instead of %y269 ret i32 %r270}271