1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64 < %s | FileCheck %s 3 4; Check that we optimize out AND instructions and ADD/SUB instructions 5; modulo the shift size to take advantage of the implicit mod done on 6; the shift amount value by the variable shift/rotate instructions. 7 8define i32 @test1(i32 %x, i64 %y) { 9; CHECK-LABEL: test1: 10; CHECK: // %bb.0: 11; CHECK-NEXT: lsr w0, w0, w1 12; CHECK-NEXT: ret 13 %sh_prom = trunc i64 %y to i32 14 %shr = lshr i32 %x, %sh_prom 15 ret i32 %shr 16} 17 18define i64 @test2(i32 %x, i64 %y) { 19; CHECK-LABEL: test2: 20; CHECK: // %bb.0: 21; CHECK-NEXT: neg w[[REG:[0-9]+]], w0 22; CHECK-NEXT: asr x0, x1, x[[REG]] 23; CHECK-NEXT: ret 24 %sub9 = sub nsw i32 64, %x 25 %sh_prom12.i = zext i32 %sub9 to i64 26 %shr.i = ashr i64 %y, %sh_prom12.i 27 ret i64 %shr.i 28} 29 30define i64 @test3(i64 %x, i64 %y) { 31; CHECK-LABEL: test3: 32; CHECK: // %bb.0: 33; CHECK-NEXT: lsl x0, x1, x0 34; CHECK-NEXT: ret 35 %add = add nsw i64 64, %x 36 %shl = shl i64 %y, %add 37 ret i64 %shl 38} 39 40define i64 @test4(i64 %y, i32 %s) { 41; CHECK-LABEL: test4: 42; CHECK: // %bb.0: // %entry 43; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 44; CHECK-NEXT: asr x0, x0, x1 45; CHECK-NEXT: ret 46entry: 47 %sh_prom = zext i32 %s to i64 48 %shr = ashr i64 %y, %sh_prom 49 ret i64 %shr 50} 51 52define i64 @test5(i64 %y, i32 %s) { 53; CHECK-LABEL: test5: 54; CHECK: // %bb.0: // %entry 55; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 56; CHECK-NEXT: asr x0, x0, x1 57; CHECK-NEXT: ret 58entry: 59 %sh_prom = sext i32 %s to i64 60 %shr = ashr i64 %y, %sh_prom 61 ret i64 %shr 62} 63 64define i64 @test6(i64 %y, i32 %s) { 65; CHECK-LABEL: test6: 66; CHECK: // %bb.0: // %entry 67; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 68; CHECK-NEXT: lsl x0, x0, x1 69; CHECK-NEXT: ret 70entry: 71 %sh_prom = sext i32 %s to i64 72 %shr = shl i64 %y, %sh_prom 73 ret i64 %shr 74} 75 76; PR42644 - https://bugs.llvm.org/show_bug.cgi?id=42644 77 78define i64 @ashr_add_shl_i32(i64 %r) { 79; CHECK-LABEL: ashr_add_shl_i32: 80; CHECK: // %bb.0: 81; CHECK-NEXT: add w8, w0, #1 // =1 82; CHECK-NEXT: sxtw x0, w8 83; CHECK-NEXT: ret 84 %conv = shl i64 %r, 32 85 %sext = add i64 %conv, 4294967296 86 %conv1 = ashr i64 %sext, 32 87 ret i64 %conv1 88} 89 90define i64 @ashr_add_shl_i8(i64 %r) { 91; CHECK-LABEL: ashr_add_shl_i8: 92; CHECK: // %bb.0: 93; CHECK-NEXT: add w8, w0, #1 // =1 94; CHECK-NEXT: sxtb x0, w8 95; CHECK-NEXT: ret 96 %conv = shl i64 %r, 56 97 %sext = add i64 %conv, 72057594037927936 98 %conv1 = ashr i64 %sext, 56 99 ret i64 %conv1 100} 101 102define <4 x i32> @ashr_add_shl_v4i8(<4 x i32> %r) { 103; CHECK-LABEL: ashr_add_shl_v4i8: 104; CHECK: // %bb.0: 105; CHECK-NEXT: shl v0.4s, v0.4s, #24 106; CHECK-NEXT: movi v1.4s, #1, lsl #24 107; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 108; CHECK-NEXT: sshr v0.4s, v0.4s, #24 109; CHECK-NEXT: ret 110 %conv = shl <4 x i32> %r, <i32 24, i32 24, i32 24, i32 24> 111 %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216> 112 %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24> 113 ret <4 x i32> %conv1 114} 115 116define i64 @ashr_add_shl_i36(i64 %r) { 117; CHECK-LABEL: ashr_add_shl_i36: 118; CHECK: // %bb.0: 119; CHECK-NEXT: sbfx x0, x0, #0, #28 120; CHECK-NEXT: ret 121 %conv = shl i64 %r, 36 122 %sext = add i64 %conv, 4294967296 123 %conv1 = ashr i64 %sext, 36 124 ret i64 %conv1 125} 126 127define i64 @ashr_add_shl_mismatch_shifts1(i64 %r) { 128; CHECK-LABEL: ashr_add_shl_mismatch_shifts1: 129; CHECK: // %bb.0: 130; CHECK-NEXT: mov x8, #4294967296 131; CHECK-NEXT: add x8, x8, x0, lsl #8 132; CHECK-NEXT: asr x0, x8, #32 133; CHECK-NEXT: ret 134 %conv = shl i64 %r, 8 135 %sext = add i64 %conv, 4294967296 136 %conv1 = ashr i64 %sext, 32 137 ret i64 %conv1 138} 139 140define i64 @ashr_add_shl_mismatch_shifts2(i64 %r) { 141; CHECK-LABEL: ashr_add_shl_mismatch_shifts2: 142; CHECK: // %bb.0: 143; CHECK-NEXT: mov x8, #4294967296 144; CHECK-NEXT: add x8, x8, x0, lsr #8 145; CHECK-NEXT: lsr x0, x8, #8 146; CHECK-NEXT: ret 147 %conv = lshr i64 %r, 8 148 %sext = add i64 %conv, 4294967296 149 %conv1 = ashr i64 %sext, 8 150 ret i64 %conv1 151} 152