1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2; RUN: llc -mtriple=aarch64 -global-isel -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s 3 4; Verify that we generate G_ASSERT_SEXT for signext parameters. 5 6define i8 @signext_param_i8(i8 signext %x) { 7 ; CHECK-LABEL: name: signext_param_i8 8 ; CHECK: bb.1 (%ir-block.0): 9 ; CHECK-NEXT: liveins: $w0 10 ; CHECK-NEXT: {{ $}} 11 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 12 ; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY]], 8 13 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_SEXT]](s32) 14 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s8) 15 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32) 16 ; CHECK-NEXT: RET_ReallyLR implicit $w0 17 ret i8 %x 18} 19 20define i8 @no_signext_param(i8 %x) { 21 ; CHECK-LABEL: name: no_signext_param 22 ; CHECK: bb.1 (%ir-block.0): 23 ; CHECK-NEXT: liveins: $w0 24 ; CHECK-NEXT: {{ $}} 25 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 26 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32) 27 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s8) 28 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32) 29 ; CHECK-NEXT: RET_ReallyLR implicit $w0 30 ret i8 %x 31} 32 33; Don't need G_ASSERT_SEXT here. The sizes match. 34define i32 @signext_param_i32(i32 signext %x) { 35 ; CHECK-LABEL: name: signext_param_i32 36 ; CHECK: bb.1 (%ir-block.0): 37 ; CHECK-NEXT: liveins: $w0 38 ; CHECK-NEXT: {{ $}} 39 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 40 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32) 41 ; CHECK-NEXT: RET_ReallyLR implicit $w0 42 ret i32 %x 43} 44 45; signext param is passed on the stack. We should still get a G_ASSERT_SEXT. 46define i32 @signext_param_stack(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, 47 ; CHECK-LABEL: name: signext_param_stack 48 ; CHECK: bb.1 (%ir-block.0): 49 ; CHECK-NEXT: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7 50 ; CHECK-NEXT: {{ $}} 51 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 52 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 53 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 54 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 55 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x4 56 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x5 57 ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x6 58 ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x7 59 ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1 60 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s64) from %fixed-stack.1, align 16) 61 ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0 62 ; CHECK-NEXT: [[SEXTLOAD:%[0-9]+]]:_(s32) = G_SEXTLOAD [[FRAME_INDEX1]](p0) :: (invariant load (s8) from %fixed-stack.0, align 8) 63 ; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[SEXTLOAD]], 1 64 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_SEXT]](s32) 65 ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s1) 66 ; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32) 67 ; CHECK-NEXT: RET_ReallyLR implicit $w0 68 i64 %g, i64 %h, i64 %i, i1 signext %j) { 69 %v = zext i1 %j to i32 70 ret i32 %v 71} 72 73; The signext parameter is a s32, so there's no extension required. 74define i32 @dont_need_assert_zext_stack(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, 75 ; CHECK-LABEL: name: dont_need_assert_zext_stack 76 ; CHECK: bb.1 (%ir-block.0): 77 ; CHECK-NEXT: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7 78 ; CHECK-NEXT: {{ $}} 79 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 80 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 81 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 82 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 83 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x4 84 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x5 85 ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x6 86 ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x7 87 ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1 88 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s64) from %fixed-stack.1, align 16) 89 ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0 90 ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (s32) from %fixed-stack.0, align 8) 91 ; CHECK-NEXT: $w0 = COPY [[LOAD1]](s32) 92 ; CHECK-NEXT: RET_ReallyLR implicit $w0 93 i64 %f, i64 %g, i64 %h, i64 %i, 94 i32 signext %j) { 95 ret i32 %j 96} 97 98; s8 requires extension to s32, so we should get a G_ASSERT_SEXT here. 99define i8 @s8_assert_zext_stack(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, 100 ; CHECK-LABEL: name: s8_assert_zext_stack 101 ; CHECK: bb.1 (%ir-block.0): 102 ; CHECK-NEXT: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7 103 ; CHECK-NEXT: {{ $}} 104 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 105 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 106 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 107 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 108 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x4 109 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x5 110 ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x6 111 ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x7 112 ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1 113 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s64) from %fixed-stack.1, align 16) 114 ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0 115 ; CHECK-NEXT: [[SEXTLOAD:%[0-9]+]]:_(s32) = G_SEXTLOAD [[FRAME_INDEX1]](p0) :: (invariant load (s8) from %fixed-stack.0, align 8) 116 ; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[SEXTLOAD]], 8 117 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_SEXT]](s32) 118 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s8) 119 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32) 120 ; CHECK-NEXT: RET_ReallyLR implicit $w0 121 i64 %f, i64 %g, i64 %h, i64 %i, 122 i8 signext %j) { 123 ret i8 %j 124} 125 126define i32 @callee_signext_i1(i1 signext %0) { 127 ; CHECK-LABEL: name: callee_signext_i1 128 ; CHECK: bb.1 (%ir-block.1): 129 ; CHECK-NEXT: liveins: $w0 130 ; CHECK-NEXT: {{ $}} 131 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 132 ; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY]], 1 133 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ASSERT_SEXT]](s32) 134 ; CHECK-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC]](s1) 135 ; CHECK-NEXT: $w0 = COPY [[SEXT]](s32) 136 ; CHECK-NEXT: RET_ReallyLR implicit $w0 137 %r = sext i1 %0 to i32 138 ret i32 %r 139} 140 141define i32 @caller_signext_i1() { 142 ; CHECK-LABEL: name: caller_signext_i1 143 ; CHECK: bb.1 (%ir-block.0): 144 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true 145 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp 146 ; CHECK-NEXT: [[SEXT:%[0-9]+]]:_(s8) = G_SEXT [[C]](s1) 147 ; CHECK-NEXT: [[SEXT1:%[0-9]+]]:_(s32) = G_SEXT [[SEXT]](s8) 148 ; CHECK-NEXT: $w0 = COPY [[SEXT1]](s32) 149 ; CHECK-NEXT: BL @callee_signext_i1, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit-def $w0 150 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp 151 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 152 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32) 153 ; CHECK-NEXT: RET_ReallyLR implicit $w0 154 %r = call i32 @callee_signext_i1(i1 signext true) 155 ret i32 %r 156} 157 158define signext i1 @ret_signext_i1() { 159 ; CHECK-LABEL: name: ret_signext_i1 160 ; CHECK: bb.1 (%ir-block.0): 161 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true 162 ; CHECK-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[C]](s1) 163 ; CHECK-NEXT: $w0 = COPY [[SEXT]](s32) 164 ; CHECK-NEXT: RET_ReallyLR implicit $w0 165 ret i1 true 166} 167