265 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: [byte1][byte0]7; Y: [byte3][byte2]8 9define i8 @out8_constmask(i8 %x, i8 %y) {10; CHECK-LABEL: out8_constmask:11; CHECK: // %bb.0:12; CHECK-NEXT: bfxil w1, w0, #0, #413; CHECK-NEXT: mov w0, w114; CHECK-NEXT: ret15 %mx = and i8 %x, 1516 %my = and i8 %y, -1617 %r = or i8 %mx, %my18 ret i8 %r19}20 21define i16 @out16_constmask(i16 %x, i16 %y) {22; CHECK-LABEL: out16_constmask:23; CHECK: // %bb.0:24; CHECK-NEXT: bfxil w1, w0, #0, #825; CHECK-NEXT: mov w0, w126; CHECK-NEXT: ret27 %mx = and i16 %x, 25528 %my = and i16 %y, -25629 %r = or i16 %mx, %my30 ret i16 %r31}32 33define i32 @out32_constmask(i32 %x, i32 %y) {34; CHECK-LABEL: out32_constmask:35; CHECK: // %bb.0:36; CHECK-NEXT: bfxil w1, w0, #0, #1637; CHECK-NEXT: mov w0, w138; CHECK-NEXT: ret39 %mx = and i32 %x, 6553540 %my = and i32 %y, -6553641 %r = or i32 %mx, %my42 ret i32 %r43}44 45define i64 @out64_constmask(i64 %x, i64 %y) {46; CHECK-LABEL: out64_constmask:47; CHECK: // %bb.0:48; CHECK-NEXT: bfxil x1, x0, #0, #3249; CHECK-NEXT: mov x0, x150; CHECK-NEXT: ret51 %mx = and i64 %x, 429496729552 %my = and i64 %y, -429496729653 %r = or i64 %mx, %my54 ret i64 %r55}56 57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58; Should be the same as the previous one.59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60 61define i8 @in8_constmask(i8 %x, i8 %y) {62; CHECK-LABEL: in8_constmask:63; CHECK: // %bb.0:64; CHECK-NEXT: eor w8, w0, w165; CHECK-NEXT: and w8, w8, #0xf66; CHECK-NEXT: eor w0, w8, w167; CHECK-NEXT: ret68 %n0 = xor i8 %x, %y69 %n1 = and i8 %n0, 1570 %r = xor i8 %n1, %y71 ret i8 %r72}73 74define i16 @in16_constmask(i16 %x, i16 %y) {75; CHECK-LABEL: in16_constmask:76; CHECK: // %bb.0:77; CHECK-NEXT: eor w8, w0, w178; CHECK-NEXT: and w8, w8, #0xff79; CHECK-NEXT: eor w0, w8, w180; CHECK-NEXT: ret81 %n0 = xor i16 %x, %y82 %n1 = and i16 %n0, 25583 %r = xor i16 %n1, %y84 ret i16 %r85}86 87define i32 @in32_constmask(i32 %x, i32 %y) {88; CHECK-LABEL: in32_constmask:89; CHECK: // %bb.0:90; CHECK-NEXT: eor w8, w0, w191; CHECK-NEXT: and w8, w8, #0xffff92; CHECK-NEXT: eor w0, w8, w193; CHECK-NEXT: ret94 %n0 = xor i32 %x, %y95 %n1 = and i32 %n0, 6553596 %r = xor i32 %n1, %y97 ret i32 %r98}99 100define i64 @in64_constmask(i64 %x, i64 %y) {101; CHECK-LABEL: in64_constmask:102; CHECK: // %bb.0:103; CHECK-NEXT: eor w8, w0, w1104; CHECK-NEXT: eor x0, x8, x1105; CHECK-NEXT: ret106 %n0 = xor i64 %x, %y107 %n1 = and i64 %n0, 4294967295108 %r = xor i64 %n1, %y109 ret i64 %r110}111 112; ============================================================================ ;113; Constant Commutativity tests.114; ============================================================================ ;115 116define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {117; CHECK-LABEL: in_constmask_commutativity_0_1:118; CHECK: // %bb.0:119; CHECK-NEXT: eor w8, w0, w1120; CHECK-NEXT: and w8, w8, #0xffff121; CHECK-NEXT: eor w0, w1, w8122; CHECK-NEXT: ret123 %n0 = xor i32 %x, %y124 %n1 = and i32 %n0, 65535125 %r = xor i32 %y, %n1 ; swapped126 ret i32 %r127}128 129define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {130; CHECK-LABEL: in_constmask_commutativity_1_0:131; CHECK: // %bb.0:132; CHECK-NEXT: eor w8, w0, w1133; CHECK-NEXT: and w8, w8, #0xffff134; CHECK-NEXT: eor w0, w8, w0135; CHECK-NEXT: ret136 %n0 = xor i32 %x, %y137 %n1 = and i32 %n0, 65535138 %r = xor i32 %n1, %x ; %x instead of %y139 ret i32 %r140}141 142define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {143; CHECK-LABEL: in_constmask_commutativity_1_1:144; CHECK: // %bb.0:145; CHECK-NEXT: eor w8, w0, w1146; CHECK-NEXT: and w8, w8, #0xffff147; CHECK-NEXT: eor w0, w0, w8148; CHECK-NEXT: ret149 %n0 = xor i32 %x, %y150 %n1 = and i32 %n0, 65535151 %r = xor i32 %x, %n1 ; swapped, %x instead of %y152 ret i32 %r153}154 155; ============================================================================ ;156; Y is an 'and' too.157; ============================================================================ ;158 159define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {160; CHECK-LABEL: in_complex_y0_constmask:161; CHECK: // %bb.0:162; CHECK-NEXT: and w8, w1, w2163; CHECK-NEXT: eor w9, w0, w8164; CHECK-NEXT: and w9, w9, #0xffff165; CHECK-NEXT: eor w0, w9, w8166; CHECK-NEXT: ret167 %y = and i32 %y_hi, %y_low168 %n0 = xor i32 %x, %y169 %n1 = and i32 %n0, 65535170 %r = xor i32 %n1, %y171 ret i32 %r172}173 174define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {175; CHECK-LABEL: in_complex_y1_constmask:176; CHECK: // %bb.0:177; CHECK-NEXT: and w8, w1, w2178; CHECK-NEXT: eor w9, w0, w8179; CHECK-NEXT: and w9, w9, #0xffff180; CHECK-NEXT: eor w0, w8, w9181; CHECK-NEXT: ret182 %y = and i32 %y_hi, %y_low183 %n0 = xor i32 %x, %y184 %n1 = and i32 %n0, 65535185 %r = xor i32 %y, %n1186 ret i32 %r187}188 189; ============================================================================ ;190; Negative tests. Should not be folded.191; ============================================================================ ;192 193; Multi-use tests.194 195declare void @use32(i32) nounwind196 197define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {198; CHECK-LABEL: in_multiuse_A_constmask:199; CHECK: // %bb.0:200; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill201; CHECK-NEXT: eor w8, w0, w1202; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill203; CHECK-NEXT: mov w19, w1204; CHECK-NEXT: and w20, w8, #0xffff205; CHECK-NEXT: mov w0, w20206; CHECK-NEXT: bl use32207; CHECK-NEXT: eor w0, w20, w19208; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload209; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload210; CHECK-NEXT: ret211 %n0 = xor i32 %x, %y212 %n1 = and i32 %n0, 65535213 call void @use32(i32 %n1)214 %r = xor i32 %n1, %y215 ret i32 %r216}217 218define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {219; CHECK-LABEL: in_multiuse_B_constmask:220; CHECK: // %bb.0:221; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill222; CHECK-NEXT: eor w0, w0, w1223; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill224; CHECK-NEXT: mov w19, w1225; CHECK-NEXT: and w20, w0, #0xffff226; CHECK-NEXT: bl use32227; CHECK-NEXT: eor w0, w20, w19228; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload229; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload230; CHECK-NEXT: ret231 %n0 = xor i32 %x, %y232 %n1 = and i32 %n0, 65535233 call void @use32(i32 %n0)234 %r = xor i32 %n1, %y235 ret i32 %r236}237 238; Various bad variants239 240define i32 @n0_badconstmask(i32 %x, i32 %y) {241; CHECK-LABEL: n0_badconstmask:242; CHECK: // %bb.0:243; CHECK-NEXT: and w8, w0, #0xffff244; CHECK-NEXT: and w9, w1, #0xffff0001245; CHECK-NEXT: orr w0, w8, w9246; CHECK-NEXT: ret247 %mx = and i32 %x, 65535248 %my = and i32 %y, -65535 ; instead of -65536249 %r = or i32 %mx, %my250 ret i32 %r251}252 253define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {254; CHECK-LABEL: n1_thirdvar_constmask:255; CHECK: // %bb.0:256; CHECK-NEXT: eor w8, w0, w1257; CHECK-NEXT: and w8, w8, #0xffff258; CHECK-NEXT: eor w0, w8, w2259; CHECK-NEXT: ret260 %n0 = xor i32 %x, %y261 %n1 = and i32 %n0, 65535262 %r = xor i32 %n1, %z ; instead of %y263 ret i32 %r264}265