Index: flang/lib/Lower/IntrinsicCall.cpp =================================================================== --- flang/lib/Lower/IntrinsicCall.cpp +++ flang/lib/Lower/IntrinsicCall.cpp @@ -504,6 +504,7 @@ mlir::Value genIshft(mlir::Type, llvm::ArrayRef); mlir::Value genIshftc(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef); + mlir::Value genLeadz(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genLenTrim(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genMatmul(mlir::Type, llvm::ArrayRef); @@ -520,6 +521,8 @@ mlir::Value genNot(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genPack(mlir::Type, llvm::ArrayRef); + mlir::Value genPopcnt(mlir::Type, llvm::ArrayRef); + mlir::Value genPoppar(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genPresent(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genProduct(mlir::Type, llvm::ArrayRef); void genRandomInit(llvm::ArrayRef); @@ -540,6 +543,7 @@ fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef); void genSystemClock(llvm::ArrayRef); + mlir::Value genTrailz(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genTransfer(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genTranspose(mlir::Type, @@ -782,6 +786,7 @@ &I::genLbound, {{{"array", asInquired}, {"dim", asValue}, {"kind", asValue}}}, /*isElemental=*/false}, + {"leadz", &I::genLeadz}, {"len", &I::genLen, {{{"string", asInquired}, {"kind", asValue}}}, @@ -845,6 +850,8 @@ {"mask", asBox}, {"vector", asBox, handleDynamicOptional}}}, /*isElemental=*/false}, + {"popcnt", &I::genPopcnt}, + {"poppar", &I::genPoppar}, {"present", &I::genPresent, {{{"a", asInquired}}}, @@ -913,6 +920,7 @@ &I::genSystemClock, {{{"count", asAddr}, {"count_rate", asAddr}, {"count_max", asAddr}}}, /*isElemental=*/false}, + {"trailz", &I::genTrailz}, {"transfer", &I::genTransfer, {{{"source", asAddr}, {"mold", asAddr}, {"size", asValue}}}, @@ -1054,6 +1062,19 @@ return mlir::FunctionType::get(context, {t, t}, {t}); } +template +static mlir::FunctionType genIntIntFuncType(mlir::MLIRContext *context) { + auto i = mlir::IntegerType::get(context, Bits); + return mlir::FunctionType::get(context, {i}, {i}); +} + +template +static mlir::FunctionType genIntIntBoolFuncType(mlir::MLIRContext *context) { + auto i = mlir::IntegerType::get(context, Bits); + auto b = mlir::IntegerType::get(context, 1); + return mlir::FunctionType::get(context, {i, b}, {i}); +} + template static mlir::FunctionType genIntF64FuncType(mlir::MLIRContext *context) { auto t = mlir::FloatType::getF64(context); @@ -1251,6 +1272,11 @@ // llvm.floor is used for FLOOR, but returns real. {"floor", "llvm.floor.f32", genF32F32FuncType}, {"floor", "llvm.floor.f64", genF64F64FuncType}, + {"leadz", "llvm.ctlz.i8", genIntIntBoolFuncType<8>}, + {"leadz", "llvm.ctlz.i16", genIntIntBoolFuncType<16>}, + {"leadz", "llvm.ctlz.i32", genIntIntBoolFuncType<32>}, + {"leadz", "llvm.ctlz.i64", genIntIntBoolFuncType<64>}, + {"leadz", "llvm.ctlz.i128", genIntIntBoolFuncType<128>}, {"log", "llvm.log.f32", genF32F32FuncType}, {"log", "llvm.log.f64", genF64F64FuncType}, {"log10", "llvm.log10.f32", genF32F32FuncType}, @@ -1259,6 +1285,11 @@ {"nint", "llvm.lround.i64.f32", genIntF32FuncType<64>}, {"nint", "llvm.lround.i32.f64", genIntF64FuncType<32>}, {"nint", "llvm.lround.i32.f32", genIntF32FuncType<32>}, + {"popcnt", "llvm.ctpop.i8", genIntIntFuncType<8>}, + {"popcnt", "llvm.ctpop.i16", genIntIntFuncType<16>}, + {"popcnt", "llvm.ctpop.i32", genIntIntFuncType<32>}, + {"popcnt", "llvm.ctpop.i64", genIntIntFuncType<64>}, + {"popcnt", "llvm.ctpop.i128", genIntIntFuncType<128>}, {"pow", "llvm.pow.f32", genF32F32F32FuncType}, {"pow", "llvm.pow.f64", genF64F64F64FuncType}, {"sign", "llvm.copysign.f32", genF32F32F32FuncType}, @@ -1271,6 +1302,11 @@ {"sinh", "sinh", genF64F64FuncType}, {"sqrt", "llvm.sqrt.f32", genF32F32FuncType}, {"sqrt", "llvm.sqrt.f64", genF64F64FuncType}, + {"trailz", "llvm.cttz.i8", genIntIntBoolFuncType<8>}, + {"trailz", "llvm.cttz.i16", genIntIntBoolFuncType<16>}, + {"trailz", "llvm.cttz.i32", genIntIntBoolFuncType<32>}, + {"trailz", "llvm.cttz.i64", genIntIntBoolFuncType<64>}, + {"trailz", "llvm.cttz.i128", genIntIntBoolFuncType<128>}, }; // This helper class computes a "distance" between two function types. @@ -3138,6 +3174,20 @@ return builder.create(loc, shiftIsNop, I, res); } +// LEADZ +mlir::Value IntrinsicLibrary::genLeadz(mlir::Type resultType, + llvm::ArrayRef args) { + assert(args.size() == 1); + + // The second argument to the llvm.ctlz.* intrinsic is a boolean indicating + // whether a zero-value for the first argument results in a poison value. + mlir::Value vf = builder.createBool(loc, false); + mlir::Value llvmArgs[2]{args[0], vf}; + mlir::Value result = genRuntimeCall("leadz", args[0].getType(), llvmArgs); + + return builder.createConvert(loc, resultType, result); +} + // LEN // Note that this is only used for an unrestricted intrinsic LEN call. // Other uses of LEN are rewritten as descriptor inquiries by the front-end. @@ -3416,6 +3466,26 @@ "unexpected result for PACK"); } +// POPCNT +mlir::Value IntrinsicLibrary::genPopcnt(mlir::Type resultType, + llvm::ArrayRef args) { + assert(args.size() == 1); + + mlir::Value count = genRuntimeCall("popcnt", args[0].getType(), args); + return builder.createConvert(loc, resultType, count); +} + +// POPPAR +mlir::Value IntrinsicLibrary::genPoppar(mlir::Type resultType, + llvm::ArrayRef args) { + assert(args.size() == 1); + + mlir::Value count = genPopcnt(resultType, args); + mlir::Value one = builder.createIntegerConstant(loc, resultType, 1); + + return builder.create(loc, count, one); +} + // PRESENT fir::ExtendedValue IntrinsicLibrary::genPresent(mlir::Type, @@ -3695,6 +3765,20 @@ .getResults()[0]; } +// TRAILZ +mlir::Value IntrinsicLibrary::genTrailz(mlir::Type resultType, + llvm::ArrayRef args) { + assert(args.size() == 1); + + // The second argument to the llvm.cttz.* intrinsic is a boolean indicating + // whether a zero-value for the first argument results in a poison value. + mlir::Value vf = builder.createBool(loc, false); + mlir::Value llvmArgs[2]{args[0], vf}; + mlir::Value result = genRuntimeCall("trailz", args[0].getType(), llvmArgs); + + return builder.createConvert(loc, resultType, result); +} + static bool hasDefaultLowerBound(const fir::ExtendedValue &exv) { return exv.match( [](const fir::ArrayBoxValue &arr) { return arr.getLBounds().empty(); }, Index: flang/test/Evaluate/fold-popcnt.f90 =================================================================== --- /dev/null +++ flang/test/Evaluate/fold-popcnt.f90 @@ -0,0 +1,174 @@ +! RUN: %python %S/test_folding.py %s %flang_fc1 +! Test counts of set bits. + +module leadz_tests + logical, parameter :: test_z1 = leadz(0_1) .EQ. 8 + logical, parameter :: test_o1 = leadz(1_1) .EQ. 7 + logical, parameter :: test_t1 = leadz(2_1) .EQ. 6 + logical, parameter :: test_f1 = leadz(15_1) .EQ. 4 + logical, parameter :: test_b1 = leadz(16_1) .EQ. 3 + logical, parameter :: test_m11 = leadz(-1_1) .EQ. 0 + logical, parameter :: test_m12 = leadz(-2_1) .EQ. 0 + logical, parameter :: test_mb1 = leadz(-120_1) .EQ. 0 + + logical, parameter :: test_z2 = leadz(0_2) .EQ. 16 + logical, parameter :: test_o2 = leadz(1_2) .EQ. 15 + logical, parameter :: test_t2 = leadz(2_2) .EQ. 14 + logical, parameter :: test_f2 = leadz(15_2) .EQ. 12 + logical, parameter :: test_m21 = leadz(-1_2) .EQ. 0 + logical, parameter :: test_m22 = leadz(-2_2) .EQ. 0 + logical, parameter :: test_mb2 = leadz(-32640_2) .EQ. 0 + + logical, parameter :: test_z4 = leadz(0_4) .EQ. 32 + logical, parameter :: test_o4 = leadz(1_4) .EQ. 31 + logical, parameter :: test_t4 = leadz(2_4) .EQ. 30 + logical, parameter :: test_f4 = leadz(15_4) .EQ. 28 + logical, parameter :: test_m41 = leadz(-1_4) .EQ. 0 + logical, parameter :: test_m42 = leadz(-2_4) .EQ. 0 + logical, parameter :: test_mb4 = leadz(-2147450880_4) .EQ. 0 + + logical, parameter :: test_z8 = leadz(0_8) .EQ. 64 + logical, parameter :: test_o8 = leadz(1_8) .EQ. 63 + logical, parameter :: test_t8 = leadz(2_8) .EQ. 62 + logical, parameter :: test_f8 = leadz(15_8) .EQ. 60 + logical, parameter :: test_m81 = leadz(-1_8) .EQ. 0 + logical, parameter :: test_m82 = leadz(-2_8) .EQ. 0 + logical, parameter :: test_mb8 = leadz(-9223372034707292160_8) .EQ. 0 + + logical, parameter :: test_z16 = leadz(0_16) .EQ. 128 + logical, parameter :: test_o16 = leadz(1_16) .EQ. 127 + logical, parameter :: test_t16 = leadz(2_16) .EQ. 126 + logical, parameter :: test_f16 = leadz(15_16) .EQ. 124 + logical, parameter :: test_m161 = leadz(-1_16) .EQ. 0 + logical, parameter :: test_m162 = leadz(-2_16) .EQ. 0 + logical, parameter :: test_mb16 = leadz(18446744073709551616_16) .EQ. 63 +end module leadz_tests + +module trailz_tests + logical, parameter :: test_z1 = trailz(0_1) .EQ. 8 + logical, parameter :: test_o1 = trailz(1_1) .EQ. 0 + logical, parameter :: test_t1 = trailz(2_1) .EQ. 1 + logical, parameter :: test_f1 = trailz(15_1) .EQ. 0 + logical, parameter :: test_b1 = trailz(16_1) .EQ. 4 + logical, parameter :: test_m11 = trailz(-1_1) .EQ. 0 + logical, parameter :: test_m12 = trailz(-2_1) .EQ. 1 + logical, parameter :: test_mb1 = trailz(-120_1) .EQ. 3 + + logical, parameter :: test_z2 = trailz(0_2) .EQ. 16 + logical, parameter :: test_o2 = trailz(1_2) .EQ. 0 + logical, parameter :: test_t2 = trailz(2_2) .EQ. 1 + logical, parameter :: test_f2 = trailz(15_2) .EQ. 0 + logical, parameter :: test_m21 = trailz(-1_2) .EQ. 0 + logical, parameter :: test_m22 = trailz(-2_2) .EQ. 1 + logical, parameter :: test_mb2 = trailz(-32640_2) .EQ. 7 + + logical, parameter :: test_z4 = trailz(0_4) .EQ. 32 + logical, parameter :: test_o4 = trailz(1_4) .EQ. 0 + logical, parameter :: test_t4 = trailz(2_4) .EQ. 1 + logical, parameter :: test_f4 = trailz(15_4) .EQ. 0 + logical, parameter :: test_m41 = trailz(-1_4) .EQ. 0 + logical, parameter :: test_m42 = trailz(-2_4) .EQ. 1 + logical, parameter :: test_mb4 = trailz(-2147450880_4) .EQ. 15 + + logical, parameter :: test_z8 = trailz(0_8) .EQ. 64 + logical, parameter :: test_o8 = trailz(1_8) .EQ. 0 + logical, parameter :: test_t8 = trailz(2_8) .EQ. 1 + logical, parameter :: test_f8 = trailz(15_8) .EQ. 0 + logical, parameter :: test_m81 = trailz(-1_8) .EQ. 0 + logical, parameter :: test_m82 = trailz(-2_8) .EQ. 1 + logical, parameter :: test_mb8 = trailz(-9223372034707292160_8) .EQ. 31 + + logical, parameter :: test_z16 = trailz(0_16) .EQ. 128 + logical, parameter :: test_o16 = trailz(1_16) .EQ. 0 + logical, parameter :: test_t16 = trailz(2_16) .EQ. 1 + logical, parameter :: test_f16 = trailz(15_16) .EQ. 0 + logical, parameter :: test_m161 = trailz(-1_16) .EQ. 0 + logical, parameter :: test_m162 = trailz(-2_16) .EQ. 1 + logical, parameter :: test_mb16 = trailz(18446744073709551616_16) .EQ. 64 +end module trailz_tests + +module popcnt_tests + logical, parameter :: test_z1 = popcnt(0_1) .EQ. 0 + logical, parameter :: test_o1 = popcnt(1_1) .EQ. 1 + logical, parameter :: test_t1 = popcnt(2_1) .EQ. 1 + logical, parameter :: test_f1 = popcnt(15_1) .EQ. 4 + logical, parameter :: test_b1 = popcnt(16_1) .EQ. 1 + logical, parameter :: test_m11 = popcnt(-1_1) .EQ. 8 + logical, parameter :: test_m12 = popcnt(-2_1) .EQ. 7 + logical, parameter :: test_mb1 = popcnt(-120_1) .EQ. 2 + + logical, parameter :: test_z2 = popcnt(0_2) .EQ. 0 + logical, parameter :: test_o2 = popcnt(1_2) .EQ. 1 + logical, parameter :: test_t2 = popcnt(2_2) .EQ. 1 + logical, parameter :: test_f2 = popcnt(15_2) .EQ. 4 + logical, parameter :: test_m21 = popcnt(-1_2) .EQ. 16 + logical, parameter :: test_m22 = popcnt(-2_2) .EQ. 15 + logical, parameter :: test_mb2 = popcnt(-32640_2) .EQ. 2 + + logical, parameter :: test_z4 = popcnt(0_4) .EQ. 0 + logical, parameter :: test_o4 = popcnt(1_4) .EQ. 1 + logical, parameter :: test_t4 = popcnt(2_4) .EQ. 1 + logical, parameter :: test_f4 = popcnt(15_4) .EQ. 4 + logical, parameter :: test_m41 = popcnt(-1_4) .EQ. 32 + logical, parameter :: test_m42 = popcnt(-2_4) .EQ. 31 + logical, parameter :: test_mb4 = popcnt(-2147450880_4) .EQ. 2 + + logical, parameter :: test_z8 = popcnt(0_8) .EQ. 0 + logical, parameter :: test_o8 = popcnt(1_8) .EQ. 1 + logical, parameter :: test_t8 = popcnt(2_8) .EQ. 1 + logical, parameter :: test_f8 = popcnt(15_8) .EQ. 4 + logical, parameter :: test_m81 = popcnt(-1_8) .EQ. 64 + logical, parameter :: test_m82 = popcnt(-2_8) .EQ. 63 + logical, parameter :: test_mb8 = popcnt(-9223372034707292160_8) .EQ. 2 + + logical, parameter :: test_z16 = popcnt(0_16) .EQ. 0 + logical, parameter :: test_o16 = popcnt(1_16) .EQ. 1 + logical, parameter :: test_t16 = popcnt(2_16) .EQ. 1 + logical, parameter :: test_f16 = popcnt(15_16) .EQ. 4 + logical, parameter :: test_m161 = popcnt(-1_16) .EQ. 128 + logical, parameter :: test_m162 = popcnt(-2_16) .EQ. 127 + logical, parameter :: test_mb16 = popcnt(18446744073709551616_16) .EQ. 1 +end module popcnt_tests + +module poppar_tests + logical, parameter :: test_z1 = poppar(0_1) .EQ. 0 + logical, parameter :: test_o1 = poppar(1_1) .EQ. 1 + logical, parameter :: test_t1 = poppar(2_1) .EQ. 1 + logical, parameter :: test_f1 = poppar(15_1) .EQ. 0 + logical, parameter :: test_b1 = poppar(16_1) .EQ. 1 + logical, parameter :: test_m11 = poppar(-1_1) .EQ. 0 + logical, parameter :: test_m12 = poppar(-2_1) .EQ. 1 + logical, parameter :: test_mb1 = poppar(-120_1) .EQ. 0 + + logical, parameter :: test_z2 = poppar(0_2) .EQ. 0 + logical, parameter :: test_o2 = poppar(1_2) .EQ. 1 + logical, parameter :: test_t2 = poppar(2_2) .EQ. 1 + logical, parameter :: test_f2 = poppar(15_2) .EQ. 0 + logical, parameter :: test_m21 = poppar(-1_2) .EQ. 0 + logical, parameter :: test_m22 = poppar(-2_2) .EQ. 1 + logical, parameter :: test_mb2 = poppar(-32640_2) .EQ. 0 + + logical, parameter :: test_z4 = poppar(0_4) .EQ. 0 + logical, parameter :: test_o4 = poppar(1_4) .EQ. 1 + logical, parameter :: test_t4 = poppar(2_4) .EQ. 1 + logical, parameter :: test_f4 = poppar(15_4) .EQ. 0 + logical, parameter :: test_m41 = poppar(-1_4) .EQ. 0 + logical, parameter :: test_m42 = poppar(-2_4) .EQ. 1 + logical, parameter :: test_mb4 = poppar(-2147450880_4) .EQ. 0 + + logical, parameter :: test_z8 = poppar(0_8) .EQ. 0 + logical, parameter :: test_o8 = poppar(1_8) .EQ. 1 + logical, parameter :: test_t8 = poppar(2_8) .EQ. 1 + logical, parameter :: test_f8 = poppar(15_8) .EQ. 0 + logical, parameter :: test_m81 = poppar(-1_8) .EQ. 0 + logical, parameter :: test_m82 = poppar(-2_8) .EQ. 1 + logical, parameter :: test_mb8 = poppar(-9223372034707292160_8) .EQ. 0 + + logical, parameter :: test_z16 = poppar(0_16) .EQ. 0 + logical, parameter :: test_o16 = poppar(1_16) .EQ. 1 + logical, parameter :: test_t16 = poppar(2_16) .EQ. 1 + logical, parameter :: test_f16 = poppar(15_16) .EQ. 0 + logical, parameter :: test_m161 = poppar(-1_16) .EQ. 0 + logical, parameter :: test_m162 = poppar(-2_16) .EQ. 1 + logical, parameter :: test_mb16 = poppar(18446744073709551616_16) .EQ. 1 +end module poppar_tests Index: flang/test/Lower/Intrinsics/leadz.f90 =================================================================== --- /dev/null +++ flang/test/Lower/Intrinsics/leadz.f90 @@ -0,0 +1,70 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: leadz1_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine leadz1_test(a, b) + integer(1) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = leadz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctlz.i8(%[[AVAL]], %[[FALSE]]) : (i8, i1) -> i8 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i8) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine leadz1_test + +! CHECK-LABEL: leadz2_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine leadz2_test(a, b) + integer(2) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = leadz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctlz.i16(%[[AVAL]], %[[FALSE]]) : (i16, i1) -> i16 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i16) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine leadz2_test + +! CHECK-LABEL: leadz4_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine leadz4_test(a, b) + integer(4) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = leadz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[RESULT:.*]] = fir.call @llvm.ctlz.i32(%[[AVAL]], %[[FALSE]]) : (i32, i1) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine leadz4_test + +! CHECK-LABEL: leadz8_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine leadz8_test(a, b) + integer(8) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = leadz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctlz.i64(%[[AVAL]], %[[FALSE]]) : (i64, i1) -> i64 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i64) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine leadz8_test + +! CHECK-LABEL: leadz16_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine leadz16_test(a, b) + integer(16) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = leadz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctlz.i128(%[[AVAL]], %[[FALSE]]) : (i128, i1) -> i128 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i128) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine leadz16_test Index: flang/test/Lower/Intrinsics/popcnt.f90 =================================================================== --- /dev/null +++ flang/test/Lower/Intrinsics/popcnt.f90 @@ -0,0 +1,65 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: popcnt1_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine popcnt1_test(a, b) + integer(1) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = popcnt(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i8(%[[AVAL]]) : (i8) -> i8 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i8) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine popcnt1_test + +! CHECK-LABEL: popcnt2_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine popcnt2_test(a, b) + integer(2) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = popcnt(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i16(%[[AVAL]]) : (i16) -> i16 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i16) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine popcnt2_test + +! CHECK-LABEL: popcnt4_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine popcnt4_test(a, b) + integer(4) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = popcnt(a) + ! CHECK: %[[RESULT:.*]] = fir.call @llvm.ctpop.i32(%[[AVAL]]) : (i32) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine popcnt4_test + +! CHECK-LABEL: popcnt8_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine popcnt8_test(a, b) + integer(8) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = popcnt(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i64(%[[AVAL]]) : (i64) -> i64 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i64) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine popcnt8_test + +! CHECK-LABEL: popcnt16_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine popcnt16_test(a, b) + integer(16) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = popcnt(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i128(%[[AVAL]]) : (i128) -> i128 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i128) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine popcnt16_test Index: flang/test/Lower/Intrinsics/poppar.f90 =================================================================== --- /dev/null +++ flang/test/Lower/Intrinsics/poppar.f90 @@ -0,0 +1,75 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: poppar1_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine poppar1_test(a, b) + integer(1) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = poppar(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i8(%[[AVAL]]) : (i8) -> i8 + ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i8) -> i32 + ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 + ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine poppar1_test + +! CHECK-LABEL: poppar2_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine poppar2_test(a, b) + integer(2) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = poppar(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i16(%[[AVAL]]) : (i16) -> i16 + ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i16) -> i32 + ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 + ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine poppar2_test + +! CHECK-LABEL: poppar4_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine poppar4_test(a, b) + integer(4) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = poppar(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i32(%[[AVAL]]) : (i32) -> i32 + ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 + ! CHECK: %[[RESULT:.*]] = arith.andi %[[COUNT]], %[[C1]] : i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine poppar4_test + +! CHECK-LABEL: poppar8_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine poppar8_test(a, b) + integer(8) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = poppar(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i64(%[[AVAL]]) : (i64) -> i64 + ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i64) -> i32 + ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 + ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine poppar8_test + +! CHECK-LABEL: poppar16_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine poppar16_test(a, b) + integer(16) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = poppar(a) + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.ctpop.i128(%[[AVAL]]) : (i128) -> i128 + ! CHECK: %[[CONV:.*]] = fir.convert %[[COUNT]] : (i128) -> i32 + ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 + ! CHECK: %[[RESULT:.*]] = arith.andi %[[CONV]], %[[C1]] : i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine poppar16_test Index: flang/test/Lower/Intrinsics/trailz.f90 =================================================================== --- /dev/null +++ flang/test/Lower/Intrinsics/trailz.f90 @@ -0,0 +1,70 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: trailz1_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine trailz1_test(a, b) + integer(1) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = trailz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.cttz.i8(%[[AVAL]], %[[FALSE]]) : (i8, i1) -> i8 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i8) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine trailz1_test + +! CHECK-LABEL: trailz2_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine trailz2_test(a, b) + integer(2) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = trailz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.cttz.i16(%[[AVAL]], %[[FALSE]]) : (i16, i1) -> i16 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i16) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine trailz2_test + +! CHECK-LABEL: trailz4_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine trailz4_test(a, b) + integer(4) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = trailz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[RESULT:.*]] = fir.call @llvm.cttz.i32(%[[AVAL]], %[[FALSE]]) : (i32, i1) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine trailz4_test + +! CHECK-LABEL: trailz8_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine trailz8_test(a, b) + integer(8) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = trailz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.cttz.i64(%[[AVAL]], %[[FALSE]]) : (i64, i1) -> i64 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i64) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine trailz8_test + +! CHECK-LABEL: trailz16_test +! CHECK-SAME: %[[AREF:.*]]: !fir.ref{{.*}}, %[[BREF:.*]]: !fir.ref{{.*}} +subroutine trailz16_test(a, b) + integer(16) :: a + integer :: b + + ! CHECK: %[[AVAL:.*]] = fir.load %[[AREF]] : !fir.ref + b = trailz(a) + ! CHECK: %[[FALSE:.*]] = arith.constant false + ! CHECK: %[[COUNT:.*]] = fir.call @llvm.cttz.i128(%[[AVAL]], %[[FALSE]]) : (i128, i1) -> i128 + ! CHECK: %[[RESULT:.*]] = fir.convert %[[COUNT]] : (i128) -> i32 + ! CHECK: fir.store %[[RESULT]] to %[[BREF]] : !fir.ref +end subroutine trailz16_test