1; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s 2 3; CHECK-LABEL: @test1 4; CHECK: sbfx {{x[0-9]+}}, x0, #23, #9 5define i64 @test1(i32 %a) { 6 %tmp = ashr i32 %a, 23 7 %ext = sext i32 %tmp to i64 8 %res = add i64 %ext, 1 9 ret i64 %res 10} 11 12; CHECK-LABEL: @test2 13; CHECK: sbfx w0, w0, #23, #8 14define signext i8 @test2(i32 %a) { 15 %tmp = ashr i32 %a, 23 16 %res = trunc i32 %tmp to i8 17 ret i8 %res 18} 19 20; CHECK-LABEL: @test3 21; CHECK: sbfx w0, w0, #23, #8 22define signext i8 @test3(i32 %a) { 23 %tmp = lshr i32 %a, 23 24 %res = trunc i32 %tmp to i8 25 ret i8 %res 26} 27 28; CHECK-LABEL: @test4 29; CHECK: sbfx w0, w0, #15, #16 30define signext i16 @test4(i32 %a) { 31 %tmp = lshr i32 %a, 15 32 %res = trunc i32 %tmp to i16 33 ret i16 %res 34} 35 36; CHECK-LABEL: @test5 37; CHECK: sbfx w0, w0, #16, #8 38define signext i8 @test5(i64 %a) { 39 %tmp = lshr i64 %a, 16 40 %res = trunc i64 %tmp to i8 41 ret i8 %res 42} 43 44; CHECK-LABEL: @test6 45; CHECK: sbfx x0, x0, #30, #8 46define signext i8 @test6(i64 %a) { 47 %tmp = lshr i64 %a, 30 48 %res = trunc i64 %tmp to i8 49 ret i8 %res 50} 51 52; CHECK-LABEL: @test7 53; CHECK: sbfx x0, x0, #23, #16 54define signext i16 @test7(i64 %a) { 55 %tmp = lshr i64 %a, 23 56 %res = trunc i64 %tmp to i16 57 ret i16 %res 58} 59 60; CHECK-LABEL: @test8 61; CHECK: asr w0, w0, #25 62define signext i8 @test8(i32 %a) { 63 %tmp = ashr i32 %a, 25 64 %res = trunc i32 %tmp to i8 65 ret i8 %res 66} 67 68; CHECK-LABEL: @test9 69; CHECK: lsr w0, w0, #25 70define signext i8 @test9(i32 %a) { 71 %tmp = lshr i32 %a, 25 72 %res = trunc i32 %tmp to i8 73 ret i8 %res 74} 75 76; CHECK-LABEL: @test10 77; CHECK: lsr x0, x0, #49 78define signext i16 @test10(i64 %a) { 79 %tmp = lshr i64 %a, 49 80 %res = trunc i64 %tmp to i16 81 ret i16 %res 82} 83 84; SHR with multiple uses is fine as SXTH and SBFX are both aliases of SBFM. 85; However, allowing the transformation means the SHR and SBFX can execute in 86; parallel. 87; 88; CHECK-LABEL: @test11 89; CHECK: lsr x1, x0, #23 90; CHECK: sbfx x0, x0, #23, #16 91define void @test11(i64 %a) { 92 %tmp = lshr i64 %a, 23 93 %res = trunc i64 %tmp to i16 94 call void @use(i16 %res, i64 %tmp) 95 ret void 96} 97 98declare void @use(i16 signext, i64) 99 100; CHECK-LABEL: test_complex_node: 101; CHECK: ldr d0, [x0], #8 102; CHECK: ubfx x[[VAL:[0-9]+]], x0, #5, #27 103; CHECK: str w[[VAL]], [x2] 104define <2 x i32> @test_complex_node(<2 x i32>* %addr, <2 x i32>** %addr2, i32* %bf ) { 105 %vec = load <2 x i32>, <2 x i32>* %addr 106 107 %vec.next = getelementptr <2 x i32>, <2 x i32>* %addr, i32 1 108 store <2 x i32>* %vec.next, <2 x i32>** %addr2 109 %lo = ptrtoint <2 x i32>* %vec.next to i32 110 111 %val = lshr i32 %lo, 5 112 store i32 %val, i32* %bf 113 114 ret <2 x i32> %vec 115} 116