brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · fb966c2 Raw
323 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi | FileCheck %s --check-prefixes=CHECK,CHECK-V73; RUN: llc < %s -mtriple=armv8-none-linux-gnueabi | FileCheck %s -check-prefixes=CHECK,CHECK-V84 5 6define i32 @f(i32 %a, i32 %b) nounwind ssp {7; CHECK-LABEL: f:8; CHECK:       @ %bb.0: @ %entry9; CHECK-NEXT:    subs r0, r0, r110; CHECK-NEXT:    movle r0, #011; CHECK-NEXT:    bx lr12entry:13  %cmp = icmp sgt i32 %a, %b14  %sub = sub nsw i32 %a, %b15  %sub. = select i1 %cmp, i32 %sub, i32 016  ret i32 %sub.17}18 19define i32 @g(i32 %a, i32 %b) nounwind ssp {20; CHECK-LABEL: g:21; CHECK:       @ %bb.0: @ %entry22; CHECK-NEXT:    subs r0, r1, r023; CHECK-NEXT:    movle r0, #024; CHECK-NEXT:    bx lr25entry:26  %cmp = icmp slt i32 %a, %b27  %sub = sub nsw i32 %b, %a28  %sub. = select i1 %cmp, i32 %sub, i32 029  ret i32 %sub.30}31 32define i32 @h(i32 %a, i32 %b) nounwind ssp {33; CHECK-LABEL: h:34; CHECK:       @ %bb.0: @ %entry35; CHECK-NEXT:    subs r0, r0, #336; CHECK-NEXT:    movle r0, r137; CHECK-NEXT:    bx lr38entry:39  %cmp = icmp sgt i32 %a, 340  %sub = sub nsw i32 %a, 341  %sub. = select i1 %cmp, i32 %sub, i32 %b42  ret i32 %sub.43}44 45; rdar://1172596546define i32 @i(i32 %a, i32 %b) nounwind readnone ssp {47; CHECK-LABEL: i:48; CHECK:       @ %bb.0: @ %entry49; CHECK-NEXT:    subs r0, r1, r050; CHECK-NEXT:    movls r0, #051; CHECK-NEXT:    bx lr52entry:53  %cmp = icmp ult i32 %a, %b54  %sub = sub i32 %b, %a55  %sub. = select i1 %cmp, i32 %sub, i32 056  ret i32 %sub.57}58 59; If CPSR is live-out, we can't remove cmp if there exists60; a swapped sub.61define i32 @j(i32 %a, i32 %b) nounwind {62; CHECK-LABEL: j:63; CHECK:       @ %bb.0: @ %entry64; CHECK-NEXT:    subs r1, r0, r165; CHECK-NEXT:    movlt r0, r166; CHECK-NEXT:    movne r0, r167; CHECK-NEXT:    bx lr68entry:69  %cmp = icmp eq i32 %b, %a70  %sub = sub nsw i32 %a, %b71  br i1 %cmp, label %if.then, label %if.else72 73if.then:74  %cmp2 = icmp sgt i32 %b, %a75  %sel = select i1 %cmp2, i32 %sub, i32 %a76  ret i32 %sel77 78if.else:79  ret i32 %sub80}81 82; If the sub/rsb instruction is predicated, we can't use the flags.83; <rdar://problem/12263428>84; Test case from MultiSource/Benchmarks/Ptrdist/bc/number.s85define i32 @bc_raise(i1 %cond) nounwind ssp {86; CHECK-LABEL: bc_raise:87; CHECK:       @ %bb.0: @ %entry88; CHECK-NEXT:    mov r1, #189; CHECK-NEXT:    tst r0, #190; CHECK-NEXT:    bic r1, r1, r091; CHECK-NEXT:    mov r0, #2392; CHECK-NEXT:    rsbeq r1, r1, #093; CHECK-NEXT:    cmp r1, #094; CHECK-NEXT:    movweq r0, #1795; CHECK-NEXT:    bx lr96entry:97  %val.2.i = select i1 %cond, i32 0, i32 198  %sub.i = sub nsw i32 0, %val.2.i99  %retval.0.i = select i1 %cond, i32 %val.2.i, i32 %sub.i100  %cmp1 = icmp eq i32 %retval.0.i, 0101  br i1 %cmp1, label %land.lhs.true, label %if.end11102 103land.lhs.true:                                    ; preds = %num2long.exit104  ret i32 17105 106if.end11:                                         ; preds = %num2long.exit107  ret i32 23108}109 110; When considering the producer of cmp's src as the subsuming instruction,111; only consider that when the comparison is to 0.112define i32 @cmp_src_nonzero(i32 %a, i32 %b, i32 %x, i32 %y) {113; CHECK-LABEL: cmp_src_nonzero:114; CHECK:       @ %bb.0: @ %entry115; CHECK-NEXT:    sub r0, r0, r1116; CHECK-NEXT:    cmp r0, #17117; CHECK-NEXT:    movne r2, r3118; CHECK-NEXT:    mov r0, r2119; CHECK-NEXT:    bx lr120entry:121  %sub = sub i32 %a, %b122  %cmp = icmp eq i32 %sub, 17123  %ret = select i1 %cmp, i32 %x, i32 %y124  ret i32 %ret125}126 127define float @float_sel(i32 %a, i32 %b, float %x, float %y) {128; CHECK-V7-LABEL: float_sel:129; CHECK-V7:       @ %bb.0: @ %entry130; CHECK-V7-NEXT:    vmov s2, r2131; CHECK-V7-NEXT:    subs r0, r0, r1132; CHECK-V7-NEXT:    vmov s0, r3133; CHECK-V7-NEXT:    vmoveq.f32 s0, s2134; CHECK-V7-NEXT:    vmov r0, s0135; CHECK-V7-NEXT:    bx lr136;137; CHECK-V8-LABEL: float_sel:138; CHECK-V8:       @ %bb.0: @ %entry139; CHECK-V8-NEXT:    subs r0, r0, r1140; CHECK-V8-NEXT:    vmov s0, r3141; CHECK-V8-NEXT:    vmov s2, r2142; CHECK-V8-NEXT:    vseleq.f32 s0, s2, s0143; CHECK-V8-NEXT:    vmov r0, s0144; CHECK-V8-NEXT:    bx lr145entry:146  %sub = sub i32 %a, %b147  %cmp = icmp eq i32 %sub, 0148  %ret = select i1 %cmp, float %x, float %y149  ret float %ret150}151 152define double @double_sel(i32 %a, i32 %b, double %x, double %y) {153; CHECK-V7-LABEL: double_sel:154; CHECK-V7:       @ %bb.0: @ %entry155; CHECK-V7-NEXT:    vmov d17, r2, r3156; CHECK-V7-NEXT:    vldr d16, [sp]157; CHECK-V7-NEXT:    subs r0, r0, r1158; CHECK-V7-NEXT:    vmoveq.f64 d16, d17159; CHECK-V7-NEXT:    vmov r0, r1, d16160; CHECK-V7-NEXT:    bx lr161;162; CHECK-V8-LABEL: double_sel:163; CHECK-V8:       @ %bb.0: @ %entry164; CHECK-V8-NEXT:    vldr d16, [sp]165; CHECK-V8-NEXT:    vmov d17, r2, r3166; CHECK-V8-NEXT:    subs r0, r0, r1167; CHECK-V8-NEXT:    vseleq.f64 d16, d17, d16168; CHECK-V8-NEXT:    vmov r0, r1, d16169; CHECK-V8-NEXT:    bx lr170entry:171  %sub = sub i32 %a, %b172  %cmp = icmp eq i32 %sub, 0173  %ret = select i1 %cmp, double %x, double %y174  ret double %ret175}176 177@t = common global i32 0178define double @double_sub(i32 %a, i32 %b, double %x, double %y) {179; CHECK-V7-LABEL: double_sub:180; CHECK-V7:       @ %bb.0: @ %entry181; CHECK-V7-NEXT:    vmov d17, r2, r3182; CHECK-V7-NEXT:    cmp r0, r1183; CHECK-V7-NEXT:    vldr d16, [sp]184; CHECK-V7-NEXT:    sub r0, r0, r1185; CHECK-V7-NEXT:    vmovgt.f64 d16, d17186; CHECK-V7-NEXT:    movw r1, :lower16:t187; CHECK-V7-NEXT:    movt r1, :upper16:t188; CHECK-V7-NEXT:    str r0, [r1]189; CHECK-V7-NEXT:    vmov r2, r3, d16190; CHECK-V7-NEXT:    mov r0, r2191; CHECK-V7-NEXT:    mov r1, r3192; CHECK-V7-NEXT:    bx lr193;194; CHECK-V8-LABEL: double_sub:195; CHECK-V8:       @ %bb.0: @ %entry196; CHECK-V8-NEXT:    vldr d16, [sp]197; CHECK-V8-NEXT:    cmp r0, r1198; CHECK-V8-NEXT:    vmov d17, r2, r3199; CHECK-V8-NEXT:    sub r0, r0, r1200; CHECK-V8-NEXT:    vselgt.f64 d16, d17, d16201; CHECK-V8-NEXT:    movw r1, :lower16:t202; CHECK-V8-NEXT:    vmov r2, r3, d16203; CHECK-V8-NEXT:    movt r1, :upper16:t204; CHECK-V8-NEXT:    str r0, [r1]205; CHECK-V8-NEXT:    mov r0, r2206; CHECK-V8-NEXT:    mov r1, r3207; CHECK-V8-NEXT:    bx lr208entry:209  %cmp = icmp sgt i32 %a, %b210  %sub = sub i32 %a, %b211  store i32 %sub, ptr @t212  %ret = select i1 %cmp, double %x, double %y213  ret double %ret214}215 216define double @double_sub_swap(i32 %a, i32 %b, double %x, double %y) {217; CHECK-V7-LABEL: double_sub_swap:218; CHECK-V7:       @ %bb.0: @ %entry219; CHECK-V7-NEXT:    vmov d17, r2, r3220; CHECK-V7-NEXT:    cmp r1, r0221; CHECK-V7-NEXT:    vldr d16, [sp]222; CHECK-V7-NEXT:    sub r0, r1, r0223; CHECK-V7-NEXT:    vmovlt.f64 d16, d17224; CHECK-V7-NEXT:    movw r1, :lower16:t225; CHECK-V7-NEXT:    movt r1, :upper16:t226; CHECK-V7-NEXT:    str r0, [r1]227; CHECK-V7-NEXT:    vmov r2, r3, d16228; CHECK-V7-NEXT:    mov r0, r2229; CHECK-V7-NEXT:    mov r1, r3230; CHECK-V7-NEXT:    bx lr231;232; CHECK-V8-LABEL: double_sub_swap:233; CHECK-V8:       @ %bb.0: @ %entry234; CHECK-V8-NEXT:    vldr d16, [sp]235; CHECK-V8-NEXT:    cmp r1, r0236; CHECK-V8-NEXT:    vmov d17, r2, r3237; CHECK-V8-NEXT:    sub r0, r1, r0238; CHECK-V8-NEXT:    vselge.f64 d16, d16, d17239; CHECK-V8-NEXT:    movw r1, :lower16:t240; CHECK-V8-NEXT:    vmov r2, r3, d16241; CHECK-V8-NEXT:    movt r1, :upper16:t242; CHECK-V8-NEXT:    str r0, [r1]243; CHECK-V8-NEXT:    mov r0, r2244; CHECK-V8-NEXT:    mov r1, r3245; CHECK-V8-NEXT:    bx lr246entry:247  %cmp = icmp sgt i32 %a, %b248  %sub = sub i32 %b, %a249  %ret = select i1 %cmp, double %x, double %y250  store i32 %sub, ptr @t251  ret double %ret252}253 254declare void @abort()255declare void @exit(i32)256 257; If the comparison uses the V bit (signed overflow/underflow), we can't258; omit the comparison.259define i32 @cmp_slt0(i32 %a, i32 %b, i32 %x, i32 %y) {260; CHECK-LABEL: cmp_slt0:261; CHECK:       @ %bb.0: @ %entry262; CHECK-NEXT:    .save {r11, lr}263; CHECK-NEXT:    push {r11, lr}264; CHECK-NEXT:    movw r0, :lower16:t265; CHECK-NEXT:    movt r0, :upper16:t266; CHECK-NEXT:    ldr r0, [r0]267; CHECK-NEXT:    sub r0, r0, #17268; CHECK-NEXT:    cmn r0, #1269; CHECK-NEXT:    ble .LBB11_2270; CHECK-NEXT:  @ %bb.1: @ %if.else271; CHECK-NEXT:    mov r0, #0272; CHECK-NEXT:    bl exit273; CHECK-NEXT:  .LBB11_2: @ %if.then274; CHECK-NEXT:    bl abort275entry:276  %load = load i32, ptr @t, align 4277  %sub = sub i32 %load, 17278  %cmp = icmp slt i32 %sub, 0279  br i1 %cmp, label %if.then, label %if.else280 281if.then:282  call void @abort()283  unreachable284 285if.else:286  call void @exit(i32 0)287  unreachable288}289 290; Same for the C bit. (Note the ult X, 0 is trivially291; false, so the DAG combiner may or may not optimize it).292define i32 @cmp_ult0(i32 %a, i32 %b, i32 %x, i32 %y) {293; CHECK-LABEL: cmp_ult0:294; CHECK:       @ %bb.0: @ %entry295; CHECK-NEXT:    .save {r11, lr}296; CHECK-NEXT:    push {r11, lr}297; CHECK-NEXT:    movw r0, :lower16:t298; CHECK-NEXT:    movt r0, :upper16:t299; CHECK-NEXT:    ldr r0, [r0]300; CHECK-NEXT:    sub r0, r0, #17301; CHECK-NEXT:    cmp r0, #0302; CHECK-NEXT:    bhs .LBB12_2303; CHECK-NEXT:  @ %bb.1: @ %if.then304; CHECK-NEXT:    bl abort305; CHECK-NEXT:  .LBB12_2: @ %if.else306; CHECK-NEXT:    mov r0, #0307; CHECK-NEXT:    bl exit308entry:309  %load = load i32, ptr @t, align 4310  %sub = sub i32 %load, 17311  %cmp = icmp ult i32 %sub, 0312  br i1 %cmp, label %if.then, label %if.else313 314if.then:315  call void @abort()316  unreachable317 318if.else:319  call void @exit(i32 0)320  unreachable321}322 323