161 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64 < %s | FileCheck %s3 4;; Check the transformation5;; CSEL 0, cttz, cc -> AND cttz numbits-16;; for cttz in the case of i32 and i64 respectively7 8;; Cases for which the optimzation takes place9define i32 @cttzi32(i32 %x) {10; CHECK-LABEL: cttzi32:11; CHECK: // %bb.0: // %entry12; CHECK-NEXT: rbit w8, w013; CHECK-NEXT: clz w8, w814; CHECK-NEXT: and w0, w8, #0x1f15; CHECK-NEXT: ret16entry:17 %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)18 %1 = icmp eq i32 %x, 019 %2 = select i1 %1, i32 0, i32 %020 ret i32 %221}22 23define i64 @cttzi64(i64 %x) {24; CHECK-LABEL: cttzi64:25; CHECK: // %bb.0: // %entry26; CHECK-NEXT: rbit x8, x027; CHECK-NEXT: clz x8, x828; CHECK-NEXT: and x0, x8, #0x3f29; CHECK-NEXT: ret30entry:31 %0 = call i64 @llvm.cttz.i64(i64 %x, i1 true)32 %1 = icmp eq i64 %x, 033 %2 = select i1 %1, i64 0, i64 %034 ret i64 %235}36 37define i32 @cttzi32ne(i32 %x) {38; CHECK-LABEL: cttzi32ne:39; CHECK: // %bb.0: // %entry40; CHECK-NEXT: rbit w8, w041; CHECK-NEXT: clz w8, w842; CHECK-NEXT: and w0, w8, #0x1f43; CHECK-NEXT: ret44entry:45 %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)46 %1 = icmp ne i32 %x, 047 %2 = select i1 %1, i32 %0, i32 048 ret i32 %249}50 51define i64 @cttzi64ne(i64 %x) {52; CHECK-LABEL: cttzi64ne:53; CHECK: // %bb.0: // %entry54; CHECK-NEXT: rbit x8, x055; CHECK-NEXT: clz x8, x856; CHECK-NEXT: and x0, x8, #0x3f57; CHECK-NEXT: ret58entry:59 %0 = call i64 @llvm.cttz.i64(i64 %x, i1 true)60 %1 = icmp ne i64 %x, 061 %2 = select i1 %1, i64 %0, i64 062 ret i64 %263}64 65define i32 @cttztrunc(i64 %x) {66; CHECK-LABEL: cttztrunc:67; CHECK: // %bb.0: // %entry68; CHECK-NEXT: rbit x8, x069; CHECK-NEXT: clz x8, x870; CHECK-NEXT: and w0, w8, #0x3f71; CHECK-NEXT: ret72entry:73 %0 = call i64 @llvm.cttz.i64(i64 %x, i1 true)74 %1 = icmp eq i64 %x, 075 %2 = select i1 %1, i64 0, i64 %076 %3 = trunc i64 %2 to i3277 ret i32 %378}79 80;; Cases for which the optimization does not take place81define i32 @cttzne(i32 %x) {82; CHECK-LABEL: cttzne:83; CHECK: // %bb.0: // %entry84; CHECK-NEXT: rbit w8, w085; CHECK-NEXT: cmp w0, #086; CHECK-NEXT: clz w8, w887; CHECK-NEXT: csel w0, wzr, w8, ne88; CHECK-NEXT: ret89entry:90 %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)91 %1 = icmp ne i32 %x, 092 %2 = select i1 %1, i32 0, i32 %093 ret i32 %294}95 96define i32 @cttzxnot0(i32 %x) {97; CHECK-LABEL: cttzxnot0:98; CHECK: // %bb.0: // %entry99; CHECK-NEXT: rbit w8, w0100; CHECK-NEXT: cmp w0, #10101; CHECK-NEXT: clz w8, w8102; CHECK-NEXT: csel w0, wzr, w8, eq103; CHECK-NEXT: ret104entry:105 %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)106 %1 = icmp eq i32 %x, 10107 %2 = select i1 %1, i32 0, i32 %0108 ret i32 %2109}110 111define i32 @cttzlhsnot0(i32 %x) {112; CHECK-LABEL: cttzlhsnot0:113; CHECK: // %bb.0: // %entry114; CHECK-NEXT: rbit w9, w0115; CHECK-NEXT: mov w8, #10 // =0xa116; CHECK-NEXT: cmp w0, #0117; CHECK-NEXT: clz w9, w9118; CHECK-NEXT: csel w0, w8, w9, eq119; CHECK-NEXT: ret120entry:121 %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)122 %1 = icmp eq i32 %x, 0123 %2 = select i1 %1, i32 10, i32 %0124 ret i32 %2125}126 127define i32 @notcttz(i32 %x) {128; CHECK-LABEL: notcttz:129; CHECK: // %bb.0: // %entry130; CHECK-NEXT: clz w8, w0131; CHECK-NEXT: cmp w0, #0132; CHECK-NEXT: csel w0, wzr, w8, eq133; CHECK-NEXT: ret134entry:135 %0 = call i32 @llvm.ctlz.i32(i32 %x, i1 true)136 %1 = icmp eq i32 %x, 0137 %2 = select i1 %1, i32 0, i32 %0138 ret i32 %2139}140 141define i32 @cttzlhsnotx(i32 %x, i32 %y) {142; CHECK-LABEL: cttzlhsnotx:143; CHECK: // %bb.0: // %entry144; CHECK-NEXT: rbit w8, w0145; CHECK-NEXT: cmp w1, #0146; CHECK-NEXT: clz w8, w8147; CHECK-NEXT: csel w0, wzr, w8, eq148; CHECK-NEXT: ret149entry:150 %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)151 %1 = icmp eq i32 %y, 0152 %2 = select i1 %1, i32 0, i32 %0153 ret i32 %2154}155 156declare i32 @llvm.cttz.i32(i32, i1)157 158declare i64 @llvm.cttz.i64(i64, i1)159 160declare i32 @llvm.ctlz.i32(i32, i1)161