159 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 62; RUN: llc < %s -mtriple=aarch64 | FileCheck %s3 4; GitHub issue #1610365 6; Positive test : umin(sub(a,b),a) with scalar types should be folded7define i64 @underflow_compare_fold_i64(i64 %a, i64 %b) {8; CHECK-LABEL: underflow_compare_fold_i64:9; CHECK: // %bb.0:10; CHECK-NEXT: sub x8, x0, x111; CHECK-NEXT: cmp x8, x012; CHECK-NEXT: csel x0, x8, x0, lo13; CHECK-NEXT: ret14 %sub = sub i64 %a, %b15 %cond = tail call i64 @llvm.umin.i64(i64 %sub, i64 %a)16 ret i64 %cond17}18 19; Positive test : umin(a,sub(a,b)) with scalar types should be folded20define i64 @underflow_compare_fold_i64_commute(i64 %a, i64 %b) {21; CHECK-LABEL: underflow_compare_fold_i64_commute:22; CHECK: // %bb.0:23; CHECK-NEXT: sub x8, x0, x124; CHECK-NEXT: cmp x0, x825; CHECK-NEXT: csel x0, x0, x8, lo26; CHECK-NEXT: ret27 %sub = sub i64 %a, %b28 %cond = tail call i64 @llvm.umin.i64(i64 %a, i64 %sub)29 ret i64 %cond30}31 32; Positive test : multi-use is OK since the sub instruction still runs once33define i64 @underflow_compare_fold_i64_multi_use(i64 %a, i64 %b, ptr addrspace(1) %ptr) {34; CHECK-LABEL: underflow_compare_fold_i64_multi_use:35; CHECK: // %bb.0:36; CHECK-NEXT: sub x8, x0, x137; CHECK-NEXT: cmp x8, x038; CHECK-NEXT: str x8, [x2]39; CHECK-NEXT: csel x0, x8, x0, lo40; CHECK-NEXT: ret41 %sub = sub i64 %a, %b42 store i64 %sub, ptr addrspace(1) %ptr43 %cond = call i64 @llvm.umin.i64(i64 %sub, i64 %a)44 ret i64 %cond45}46 47; Positive test : i3248define i32 @underflow_compare_fold_i32(i32 %a, i32 %b) {49; CHECK-LABEL: underflow_compare_fold_i32:50; CHECK: // %bb.0:51; CHECK-NEXT: sub w8, w0, w152; CHECK-NEXT: cmp w8, w053; CHECK-NEXT: csel w0, w8, w0, lo54; CHECK-NEXT: ret55 %sub = sub i32 %a, %b56 %cond = tail call i32 @llvm.umin.i32(i32 %sub, i32 %a)57 ret i32 %cond58}59 60; Positive test : i3261define i32 @underflow_compare_fold_i32_commute(i32 %a, i32 %b) {62; CHECK-LABEL: underflow_compare_fold_i32_commute:63; CHECK: // %bb.0:64; CHECK-NEXT: sub w8, w0, w165; CHECK-NEXT: cmp w0, w866; CHECK-NEXT: csel w0, w0, w8, lo67; CHECK-NEXT: ret68 %sub = sub i32 %a, %b69 %cond = tail call i32 @llvm.umin.i32(i32 %a, i32 %sub)70 ret i32 %cond71}72 73; Positive test : i3274define i32 @underflow_compare_fold_i32_multi_use(i32 %a, i32 %b, ptr addrspace(1) %ptr) {75; CHECK-LABEL: underflow_compare_fold_i32_multi_use:76; CHECK: // %bb.0:77; CHECK-NEXT: sub w8, w0, w178; CHECK-NEXT: cmp w8, w079; CHECK-NEXT: str w8, [x2]80; CHECK-NEXT: csel w0, w8, w0, lo81; CHECK-NEXT: ret82 %sub = sub i32 %a, %b83 store i32 %sub, ptr addrspace(1) %ptr84 %cond = call i32 @llvm.umin.i32(i32 %sub, i32 %a)85 ret i32 %cond86}87 88; Negative test : i1689define i16 @underflow_compare_fold_i16(i16 %a, i16 %b) {90; CHECK-LABEL: underflow_compare_fold_i16:91; CHECK: // %bb.0:92; CHECK-NEXT: sub w8, w0, w193; CHECK-NEXT: and w9, w0, #0xffff94; CHECK-NEXT: and w8, w8, #0xffff95; CHECK-NEXT: cmp w8, w996; CHECK-NEXT: csel w0, w8, w9, lo97; CHECK-NEXT: ret98 %sub = sub i16 %a, %b99 %cond = tail call i16 @llvm.umin.i16(i16 %sub, i16 %a)100 ret i16 %cond101}102 103; Negative test : i16104define i16 @underflow_compare_fold_i16_commute(i16 %a, i16 %b) {105; CHECK-LABEL: underflow_compare_fold_i16_commute:106; CHECK: // %bb.0:107; CHECK-NEXT: sub w8, w0, w1108; CHECK-NEXT: and w9, w0, #0xffff109; CHECK-NEXT: and w8, w8, #0xffff110; CHECK-NEXT: cmp w9, w8111; CHECK-NEXT: csel w0, w9, w8, lo112; CHECK-NEXT: ret113 %sub = sub i16 %a, %b114 %cond = tail call i16 @llvm.umin.i16(i16 %a, i16 %sub)115 ret i16 %cond116}117 118; Negative test : i16119define i16 @underflow_compare_fold_i16_multi_use(i16 %a, i16 %b, ptr addrspace(1) %ptr) {120; CHECK-LABEL: underflow_compare_fold_i16_multi_use:121; CHECK: // %bb.0:122; CHECK-NEXT: sub w8, w0, w1123; CHECK-NEXT: and w9, w0, #0xffff124; CHECK-NEXT: and w10, w8, #0xffff125; CHECK-NEXT: strh w8, [x2]126; CHECK-NEXT: cmp w10, w9127; CHECK-NEXT: csel w0, w10, w9, lo128; CHECK-NEXT: ret129 %sub = sub i16 %a, %b130 store i16 %sub, ptr addrspace(1) %ptr131 %cond = call i16 @llvm.umin.i16(i16 %sub, i16 %a)132 ret i16 %cond133}134 135; Negative test, vector types : umin(sub(a,b),a) but with vectors136define <16 x i8> @underflow_compare_dontfold_vectors(<16 x i8> %a, <16 x i8> %b) {137; CHECK-LABEL: underflow_compare_dontfold_vectors:138; CHECK: // %bb.0:139; CHECK-NEXT: sub v1.16b, v0.16b, v1.16b140; CHECK-NEXT: umin v0.16b, v1.16b, v0.16b141; CHECK-NEXT: ret142 %sub = sub <16 x i8> %a, %b143 %cond = tail call <16 x i8> @llvm.umin.v16i8(<16 x i8> %sub, <16 x i8> %a)144 ret <16 x i8> %cond145}146 147; Negative test, pattern mismatch : umin(add(a,b),a)148define i64 @umin_add(i64 %a, i64 %b) {149; CHECK-LABEL: umin_add:150; CHECK: // %bb.0:151; CHECK-NEXT: add x8, x0, x1152; CHECK-NEXT: cmp x8, x0153; CHECK-NEXT: csel x0, x8, x0, lo154; CHECK-NEXT: ret155 %add = add i64 %a, %b156 %cond = tail call i64 @llvm.umin.i64(i64 %add, i64 %a)157 ret i64 %cond158}159