brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.8 KiB · ff9374f Raw
386 lines · plain
1; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s2;3; <rdar://problem/14486451>4 5%struct.a = type [256 x i16]6%struct.b = type [256 x i32]7%struct.c = type [256 x i64]8 9define i16 @load_halfword(ptr %ctx, i32 %xor72) nounwind {10; CHECK-LABEL: load_halfword:11; CHECK: ubfx [[REG:x[0-9]+]], x1, #9, #812; CHECK: ldrh w0, [x0, [[REG]], lsl #1]13  %shr81 = lshr i32 %xor72, 914  %conv82 = zext i32 %shr81 to i6415  %idxprom83 = and i64 %conv82, 25516  %arrayidx86 = getelementptr inbounds %struct.a, ptr %ctx, i64 0, i64 %idxprom8317  %result = load i16, ptr %arrayidx86, align 218  ret i16 %result19}20 21define i32 @load_word(ptr %ctx, i32 %xor72) nounwind {22; CHECK-LABEL: load_word:23; CHECK: ubfx [[REG:x[0-9]+]], x1, #9, #824; CHECK: ldr w0, [x0, [[REG]], lsl #2]25  %shr81 = lshr i32 %xor72, 926  %conv82 = zext i32 %shr81 to i6427  %idxprom83 = and i64 %conv82, 25528  %arrayidx86 = getelementptr inbounds %struct.b, ptr %ctx, i64 0, i64 %idxprom8329  %result = load i32, ptr %arrayidx86, align 430  ret i32 %result31}32 33define i64 @load_doubleword(ptr %ctx, i32 %xor72) nounwind {34; CHECK-LABEL: load_doubleword:35; CHECK: ubfx [[REG:x[0-9]+]], x1, #9, #836; CHECK: ldr x0, [x0, [[REG]], lsl #3]37  %shr81 = lshr i32 %xor72, 938  %conv82 = zext i32 %shr81 to i6439  %idxprom83 = and i64 %conv82, 25540  %arrayidx86 = getelementptr inbounds %struct.c, ptr %ctx, i64 0, i64 %idxprom8341  %result = load i64, ptr %arrayidx86, align 842  ret i64 %result43}44 45define void @store_halfword(ptr %ctx, i32 %xor72, i16 %val) nounwind {46; CHECK-LABEL: store_halfword:47; CHECK: ubfx [[REG:x[0-9]+]], x1, #9, #848; CHECK: strh w2, [x0, [[REG]], lsl #1]49  %shr81 = lshr i32 %xor72, 950  %conv82 = zext i32 %shr81 to i6451  %idxprom83 = and i64 %conv82, 25552  %arrayidx86 = getelementptr inbounds %struct.a, ptr %ctx, i64 0, i64 %idxprom8353  store i16 %val, ptr %arrayidx86, align 854  ret void55}56 57define void @store_word(ptr %ctx, i32 %xor72, i32 %val) nounwind {58; CHECK-LABEL: store_word:59; CHECK: ubfx [[REG:x[0-9]+]], x1, #9, #860; CHECK: str w2, [x0, [[REG]], lsl #2]61  %shr81 = lshr i32 %xor72, 962  %conv82 = zext i32 %shr81 to i6463  %idxprom83 = and i64 %conv82, 25564  %arrayidx86 = getelementptr inbounds %struct.b, ptr %ctx, i64 0, i64 %idxprom8365  store i32 %val, ptr %arrayidx86, align 866  ret void67}68 69define void @store_doubleword(ptr %ctx, i32 %xor72, i64 %val) nounwind {70; CHECK-LABEL: store_doubleword:71; CHECK: ubfx [[REG:x[0-9]+]], x1, #9, #872; CHECK: str x2, [x0, [[REG]], lsl #3]73  %shr81 = lshr i32 %xor72, 974  %conv82 = zext i32 %shr81 to i6475  %idxprom83 = and i64 %conv82, 25576  %arrayidx86 = getelementptr inbounds %struct.c, ptr %ctx, i64 0, i64 %idxprom8377  store i64 %val, ptr %arrayidx86, align 878  ret void79}80 81; Check that we combine a shift into the offset instead of using a narrower load82; when we have a load followed by a trunc83 84define i32 @load_doubleword_trunc_word(ptr %ptr, i64 %off) {85; CHECK-LABEL: load_doubleword_trunc_word:86; CHECK: ldr x0, [x0, x1, lsl #3]87entry:88  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off89  %x = load i64, ptr %idx, align 890  %trunc = trunc i64 %x to i3291  ret i32 %trunc92}93 94define i16 @load_doubleword_trunc_halfword(ptr %ptr, i64 %off) {95; CHECK-LABEL: load_doubleword_trunc_halfword:96; CHECK: ldr x0, [x0, x1, lsl #3]97entry:98  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off99  %x = load i64, ptr %idx, align 8100  %trunc = trunc i64 %x to i16101  ret i16 %trunc102}103 104define i8 @load_doubleword_trunc_byte(ptr %ptr, i64 %off) {105; CHECK-LABEL: load_doubleword_trunc_byte:106; CHECK: ldr x0, [x0, x1, lsl #3]107entry:108  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off109  %x = load i64, ptr %idx, align 8110  %trunc = trunc i64 %x to i8111  ret i8 %trunc112}113 114define i16 @load_word_trunc_halfword(ptr %ptr, i64 %off) {115entry:116; CHECK-LABEL: load_word_trunc_halfword:117; CHECK: ldr w0, [x0, x1, lsl #2]118  %idx = getelementptr inbounds i32, ptr %ptr, i64 %off119  %x = load i32, ptr %idx, align 8120  %trunc = trunc i32 %x to i16121  ret i16 %trunc122}123 124define i8 @load_word_trunc_byte(ptr %ptr, i64 %off) {125; CHECK-LABEL: load_word_trunc_byte:126; CHECK: ldr w0, [x0, x1, lsl #2]127entry:128 %idx = getelementptr inbounds i32, ptr %ptr, i64 %off129 %x = load i32, ptr %idx, align 8130 %trunc = trunc i32 %x to i8131 ret i8 %trunc132}133 134define i8 @load_halfword_trunc_byte(ptr %ptr, i64 %off) {135; CHECK-LABEL: load_halfword_trunc_byte:136; CHECK: ldrh w0, [x0, x1, lsl #1]137entry:138 %idx = getelementptr inbounds i16, ptr %ptr, i64 %off139 %x = load i16, ptr %idx, align 8140 %trunc = trunc i16 %x to i8141 ret i8 %trunc142}143 144; Check that we do use a narrower load, and so don't combine the shift, when145; the loaded value is zero-extended.146 147define i64 @load_doubleword_trunc_word_zext(ptr %ptr, i64 %off) {148; CHECK-LABEL: load_doubleword_trunc_word_zext:149; CHECK: lsl [[REG:x[0-9]+]], x1, #3150; CHECK: ldr w0, [x0, [[REG]]]151entry:152  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off153  %x = load i64, ptr %idx, align 8154  %trunc = trunc i64 %x to i32155  %ext = zext i32 %trunc to i64156  ret i64 %ext157}158 159define i64 @load_doubleword_trunc_halfword_zext(ptr %ptr, i64 %off) {160; CHECK-LABEL: load_doubleword_trunc_halfword_zext:161; CHECK: lsl [[REG:x[0-9]+]], x1, #3162; CHECK: ldrh w0, [x0, [[REG]]]163entry:164  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off165  %x = load i64, ptr %idx, align 8166  %trunc = trunc i64 %x to i16167  %ext = zext i16 %trunc to i64168  ret i64 %ext169}170 171define i64 @load_doubleword_trunc_byte_zext(ptr %ptr, i64 %off) {172; CHECK-LABEL: load_doubleword_trunc_byte_zext:173; CHECK: lsl [[REG:x[0-9]+]], x1, #3174; CHECK: ldrb w0, [x0, [[REG]]]175entry:176  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off177  %x = load i64, ptr %idx, align 8178  %trunc = trunc i64 %x to i8179  %ext = zext i8 %trunc to i64180  ret i64 %ext181}182 183define i64 @load_word_trunc_halfword_zext(ptr %ptr, i64 %off) {184; CHECK-LABEL: load_word_trunc_halfword_zext:185; CHECK: lsl [[REG:x[0-9]+]], x1, #2186; CHECK: ldrh w0, [x0, [[REG]]]187entry:188  %idx = getelementptr inbounds i32, ptr %ptr, i64 %off189  %x = load i32, ptr %idx, align 8190  %trunc = trunc i32 %x to i16191  %ext = zext i16 %trunc to i64192  ret i64 %ext193}194 195define i64 @load_word_trunc_byte_zext(ptr %ptr, i64 %off) {196; CHECK-LABEL: load_word_trunc_byte_zext:197; CHECK: lsl [[REG:x[0-9]+]], x1, #2198; CHECK: ldrb w0, [x0, [[REG]]]199entry:200 %idx = getelementptr inbounds i32, ptr %ptr, i64 %off201 %x = load i32, ptr %idx, align 8202 %trunc = trunc i32 %x to i8203 %ext = zext i8 %trunc to i64204 ret i64 %ext205}206 207define i64 @load_halfword_trunc_byte_zext(ptr %ptr, i64 %off) {208; CHECK-LABEL: load_halfword_trunc_byte_zext:209; CHECK: lsl [[REG:x[0-9]+]], x1, #1210; CHECK: ldrb w0, [x0, [[REG]]]211entry:212 %idx = getelementptr inbounds i16, ptr %ptr, i64 %off213 %x = load i16, ptr %idx, align 8214 %trunc = trunc i16 %x to i8215 %ext = zext i8 %trunc to i64216 ret i64 %ext217}218 219; Check that we do use a narrower load, and so don't combine the shift, when220; the loaded value is sign-extended.221 222define i64 @load_doubleword_trunc_word_sext(ptr %ptr, i64 %off) {223; CHECK-LABEL: load_doubleword_trunc_word_sext:224; CHECK: lsl [[REG:x[0-9]+]], x1, #3225; CHECK: ldrsw x0, [x0, [[REG]]]226entry:227  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off228  %x = load i64, ptr %idx, align 8229  %trunc = trunc i64 %x to i32230  %ext = sext i32 %trunc to i64231  ret i64 %ext232}233 234define i64 @load_doubleword_trunc_halfword_sext(ptr %ptr, i64 %off) {235; CHECK-LABEL: load_doubleword_trunc_halfword_sext:236; CHECK: lsl [[REG:x[0-9]+]], x1, #3237; CHECK: ldrsh x0, [x0, [[REG]]]238entry:239  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off240  %x = load i64, ptr %idx, align 8241  %trunc = trunc i64 %x to i16242  %ext = sext i16 %trunc to i64243  ret i64 %ext244}245 246define i64 @load_doubleword_trunc_byte_sext(ptr %ptr, i64 %off) {247; CHECK-LABEL: load_doubleword_trunc_byte_sext:248; CHECK: lsl [[REG:x[0-9]+]], x1, #3249; CHECK: ldrsb x0, [x0, [[REG]]]250entry:251  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off252  %x = load i64, ptr %idx, align 8253  %trunc = trunc i64 %x to i8254  %ext = sext i8 %trunc to i64255  ret i64 %ext256}257 258define i64 @load_word_trunc_halfword_sext(ptr %ptr, i64 %off) {259; CHECK-LABEL: load_word_trunc_halfword_sext:260; CHECK: lsl [[REG:x[0-9]+]], x1, #2261; CHECK: ldrsh x0, [x0, [[REG]]]262entry:263  %idx = getelementptr inbounds i32, ptr %ptr, i64 %off264  %x = load i32, ptr %idx, align 8265  %trunc = trunc i32 %x to i16266  %ext = sext i16 %trunc to i64267  ret i64 %ext268}269 270define i64 @load_word_trunc_byte_sext(ptr %ptr, i64 %off) {271; CHECK-LABEL: load_word_trunc_byte_sext:272; CHECK: lsl [[REG:x[0-9]+]], x1, #2273; CHECK: ldrsb x0, [x0, [[REG]]]274entry:275 %idx = getelementptr inbounds i32, ptr %ptr, i64 %off276 %x = load i32, ptr %idx, align 8277 %trunc = trunc i32 %x to i8278 %ext = sext i8 %trunc to i64279 ret i64 %ext280}281 282define i64 @load_halfword_trunc_byte_sext(ptr %ptr, i64 %off) {283; CHECK-LABEL: load_halfword_trunc_byte_sext:284; CHECK: lsl [[REG:x[0-9]+]], x1, #1285; CHECK: ldrsb x0, [x0, [[REG]]]286entry:287 %idx = getelementptr inbounds i16, ptr %ptr, i64 %off288 %x = load i16, ptr %idx, align 8289 %trunc = trunc i16 %x to i8290 %ext = sext i8 %trunc to i64291 ret i64 %ext292}293 294; Check that we don't combine the shift, and so will use a narrower load, when295; the shift is used more than once.296 297define i32 @load_doubleword_trunc_word_reuse_shift(ptr %ptr, i64 %off) {298; CHECK-LABEL: load_doubleword_trunc_word_reuse_shift:299; CHECK: lsl x[[REG1:[0-9]+]], x1, #3300; CHECK: ldr w[[REG2:[0-9]+]], [x0, x[[REG1]]]301; CHECK: add w0, w[[REG2]], w[[REG1]]302entry:303  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off304  %x = load i64, ptr %idx, align 8305  %trunc = trunc i64 %x to i32306  %lsl = shl i64 %off, 3307  %lsl.trunc = trunc i64 %lsl to i32308  %add = add i32 %trunc, %lsl.trunc309  ret i32 %add310}311 312define i16 @load_doubleword_trunc_halfword_reuse_shift(ptr %ptr, i64 %off) {313; CHECK-LABEL: load_doubleword_trunc_halfword_reuse_shift:314; CHECK: lsl x[[REG1:[0-9]+]], x1, #3315; CHECK: ldrh w[[REG2:[0-9]+]], [x0, x[[REG1]]]316; CHECK: add w0, w[[REG2]], w[[REG1]]317entry:318  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off319  %x = load i64, ptr %idx, align 8320  %trunc = trunc i64 %x to i16321  %lsl = shl i64 %off, 3322  %lsl.trunc = trunc i64 %lsl to i16323  %add = add i16 %trunc, %lsl.trunc324  ret i16 %add325}326 327define i8 @load_doubleword_trunc_byte_reuse_shift(ptr %ptr, i64 %off) {328; CHECK-LABEL: load_doubleword_trunc_byte_reuse_shift:329; CHECK: lsl x[[REG1:[0-9]+]], x1, #3330; CHECK: ldrb w[[REG2:[0-9]+]], [x0, x[[REG1]]]331; CHECK: add w0, w[[REG2]], w[[REG1]]332entry:333  %idx = getelementptr inbounds i64, ptr %ptr, i64 %off334  %x = load i64, ptr %idx, align 8335  %trunc = trunc i64 %x to i8336  %lsl = shl i64 %off, 3337  %lsl.trunc = trunc i64 %lsl to i8338  %add = add i8 %trunc, %lsl.trunc339  ret i8 %add340}341 342define i16 @load_word_trunc_halfword_reuse_shift(ptr %ptr, i64 %off) {343entry:344; CHECK-LABEL: load_word_trunc_halfword_reuse_shift:345; CHECK: lsl x[[REG1:[0-9]+]], x1, #2346; CHECK: ldrh w[[REG2:[0-9]+]], [x0, x[[REG1]]]347; CHECK: add w0, w[[REG2]], w[[REG1]]348  %idx = getelementptr inbounds i32, ptr %ptr, i64 %off349  %x = load i32, ptr %idx, align 8350  %trunc = trunc i32 %x to i16351  %lsl = shl i64 %off, 2352  %lsl.trunc = trunc i64 %lsl to i16353  %add = add i16 %trunc, %lsl.trunc354  ret i16 %add355}356 357define i8 @load_word_trunc_byte_reuse_shift(ptr %ptr, i64 %off) {358; CHECK-LABEL: load_word_trunc_byte_reuse_shift:359; CHECK: lsl x[[REG1:[0-9]+]], x1, #2360; CHECK: ldrb w[[REG2:[0-9]+]], [x0, x[[REG1]]]361; CHECK: add w0, w[[REG2]], w[[REG1]]362entry:363  %idx = getelementptr inbounds i32, ptr %ptr, i64 %off364  %x = load i32, ptr %idx, align 8365  %trunc = trunc i32 %x to i8366  %lsl = shl i64 %off, 2367  %lsl.trunc = trunc i64 %lsl to i8368  %add = add i8 %trunc, %lsl.trunc369  ret i8 %add370}371 372define i8 @load_halfword_trunc_byte_reuse_shift(ptr %ptr, i64 %off) {373; CHECK-LABEL: load_halfword_trunc_byte_reuse_shift:374; CHECK: lsl x[[REG1:[0-9]+]], x1, #1375; CHECK: ldrb w[[REG2:[0-9]+]], [x0, x[[REG1]]]376; CHECK: add w0, w[[REG2]], w[[REG1]]377entry:378  %idx = getelementptr inbounds i16, ptr %ptr, i64 %off379  %x = load i16, ptr %idx, align 8380  %trunc = trunc i16 %x to i8381  %lsl = shl i64 %off, 1382  %lsl.trunc = trunc i64 %lsl to i8383  %add = add i8 %trunc, %lsl.trunc384  ret i8 %add385}386