[flang] Lower F08 shift intrinsics

Lower F08 shift (shiftl, shiftr, shifta) and combined shift (dshiftl, dshiftr)
intrinsics. The combined shift intrinsics are implemented using the
definitions of shiftl and shiftr as described by the standard.

For non-conformant arguments to the shift intrinsics, the implementation tries
to replicate the behavior of other compilers if most of the other behave
consistently.

Differential Revision: https://reviews.llvm.org/D129316
This commit is contained in:
Tarun Prabhu 2022-07-21 23:36:08 -06:00
parent 2ab0aeaae2
commit 72ac3e90da
6 changed files with 698 additions and 0 deletions

View File

@ -483,6 +483,8 @@ struct IntrinsicLibrary {
fir::ExtendedValue genDotProduct(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genDprod(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genDshiftl(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genDshiftr(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genEoshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genExit(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genExponent(mlir::Type, llvm::ArrayRef<mlir::Value>);
@ -543,6 +545,8 @@ struct IntrinsicLibrary {
fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genSetExponent(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args);
template <typename Shift>
mlir::Value genShift(mlir::Type resultType, llvm::ArrayRef<mlir::Value>);
mlir::Value genSign(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genSpacing(mlir::Type resultType,
@ -741,6 +745,8 @@ static constexpr IntrinsicHandler handlers[]{
{{{"vector_a", asBox}, {"vector_b", asBox}}},
/*isElemental=*/false},
{"dprod", &I::genDprod},
{"dshiftl", &I::genDshiftl},
{"dshiftr", &I::genDshiftr},
{"eoshift",
&I::genEoshift,
{{{"array", asBox},
@ -910,6 +916,9 @@ static constexpr IntrinsicHandler handlers[]{
{"kind", asValue}}},
/*isElemental=*/true},
{"set_exponent", &I::genSetExponent},
{"shifta", &I::genShift<mlir::arith::ShRSIOp>},
{"shiftl", &I::genShift<mlir::arith::ShLIOp>},
{"shiftr", &I::genShift<mlir::arith::ShRUIOp>},
{"sign", &I::genSign},
{"size",
&I::genSize,
@ -2664,6 +2673,54 @@ mlir::Value IntrinsicLibrary::genDprod(mlir::Type resultType,
return builder.create<mlir::arith::MulFOp>(loc, a, b);
}
// DSHIFTL
mlir::Value IntrinsicLibrary::genDshiftl(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
assert(args.size() == 3);
mlir::Value i = args[0];
mlir::Value j = args[1];
mlir::Value shift = builder.createConvert(loc, resultType, args[2]);
mlir::Value bitSize = builder.createIntegerConstant(
loc, resultType, resultType.getIntOrFloatBitWidth());
// Per the standard, the value of DSHIFTL(I, J, SHIFT) is equal to
// IOR (SHIFTL(I, SHIFT), SHIFTR(J, BIT_SIZE(J) - SHIFT))
mlir::Value diff = builder.create<mlir::arith::SubIOp>(loc, bitSize, shift);
mlir::Value lArgs[2]{i, shift};
mlir::Value lft = genShift<mlir::arith::ShLIOp>(resultType, lArgs);
mlir::Value rArgs[2]{j, diff};
mlir::Value rgt = genShift<mlir::arith::ShRUIOp>(resultType, rArgs);
return builder.create<mlir::arith::OrIOp>(loc, lft, rgt);
}
// DSHIFTR
mlir::Value IntrinsicLibrary::genDshiftr(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
assert(args.size() == 3);
mlir::Value i = args[0];
mlir::Value j = args[1];
mlir::Value shift = builder.createConvert(loc, resultType, args[2]);
mlir::Value bitSize = builder.createIntegerConstant(
loc, resultType, resultType.getIntOrFloatBitWidth());
// Per the standard, the value of DSHIFTR(I, J, SHIFT) is equal to
// IOR (SHIFTL(I, BIT_SIZE(I) - SHIFT), SHIFTR(J, SHIFT))
mlir::Value diff = builder.create<mlir::arith::SubIOp>(loc, bitSize, shift);
mlir::Value lArgs[2]{i, diff};
mlir::Value lft = genShift<mlir::arith::ShLIOp>(resultType, lArgs);
mlir::Value rArgs[2]{j, shift};
mlir::Value rgt = genShift<mlir::arith::ShRUIOp>(resultType, rArgs);
return builder.create<mlir::arith::OrIOp>(loc, lft, rgt);
}
// EOSHIFT
fir::ExtendedValue
IntrinsicLibrary::genEoshift(mlir::Type resultType,
@ -3755,6 +3812,32 @@ mlir::Value IntrinsicLibrary::genSetExponent(mlir::Type resultType,
fir::getBase(args[1])));
}
// SHIFTA, SHIFTL, SHIFTR
template <typename Shift>
mlir::Value IntrinsicLibrary::genShift(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
assert(args.size() == 2);
// If SHIFT < 0 or SHIFT >= BIT_SIZE(I), return 0. This is not required by
// the standard. However, several other compilers behave this way, so try and
// maintain compatibility with them to an extent.
unsigned bits = resultType.getIntOrFloatBitWidth();
mlir::Value bitSize = builder.createIntegerConstant(loc, resultType, bits);
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
mlir::Value shift = builder.createConvert(loc, resultType, args[1]);
mlir::Value tooSmall = builder.create<mlir::arith::CmpIOp>(
loc, mlir::arith::CmpIPredicate::slt, shift, zero);
mlir::Value tooLarge = builder.create<mlir::arith::CmpIOp>(
loc, mlir::arith::CmpIPredicate::sge, shift, bitSize);
mlir::Value outOfBounds =
builder.create<mlir::arith::OrIOp>(loc, tooSmall, tooLarge);
mlir::Value shifted = builder.create<Shift>(loc, args[0], shift);
return builder.create<mlir::arith::SelectOp>(loc, outOfBounds, zero, shifted);
}
// SIGN
mlir::Value IntrinsicLibrary::genSign(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {

View File

@ -0,0 +1,156 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: dshiftl1_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i8>{{.*}}, %[[B:.*]]: !fir.ref<i8>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i8>{{.*}}
subroutine dshiftl1_test(a, b, s, c)
integer(kind=1) :: a, b
integer :: s
integer(kind=1) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i8>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i8>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftl(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i8
! CHECK: %[[C_BITS:.*]] = arith.constant 8 : i8
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i8
! CHECK: %[[C_BITS_L:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i8
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_L]] : i8
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_L]] : i8
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[S_CONV]] : i8
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i8
! CHECK: %[[C_BITS_R:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i8
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_R]] : i8
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_R]] : i8
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[DIFF]] : i8
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i8
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i8
end subroutine dshiftl1_test
! CHECK-LABEL: dshiftl2_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i16>{{.*}}, %[[B:.*]]: !fir.ref<i16>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i16>{{.*}}
subroutine dshiftl2_test(a, b, s, c)
integer(kind=2) :: a, b
integer :: s
integer(kind=2) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i16>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i16>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftl(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i16
! CHECK: %[[C_BITS:.*]] = arith.constant 16 : i16
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i16
! CHECK: %[[C_BITS_L:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i16
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_L]] : i16
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_L]] : i16
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[S_CONV]] : i16
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i16
! CHECK: %[[C_BITS_R:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i16
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_R]] : i16
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_R]] : i16
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[DIFF]] : i16
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i16
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i16
end subroutine dshiftl2_test
! CHECK-LABEL: dshiftl4_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i32>{{.*}}
subroutine dshiftl4_test(a, b, s, c)
integer(kind=4) :: a, b
integer :: s
integer(kind=4) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftl(a, b, s)
! CHECK: %[[C_BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_VAL]] : i32
! CHECK: %[[C_BITS_L:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[S_VAL]], %[[C_0_L]] : i32
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[S_VAL]], %[[C_BITS_L]] : i32
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[S_VAL]] : i32
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i32
! CHECK: %[[C_BITS_R:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_R]] : i32
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_R]] : i32
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[DIFF]] : i32
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i32
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i32
end subroutine dshiftl4_test
! CHECK-LABEL: dshiftl8_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i64>{{.*}}, %[[B:.*]]: !fir.ref<i64>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i64>{{.*}}
subroutine dshiftl8_test(a, b, s, c)
integer(kind=8) :: a, b
integer :: s
integer(kind=8) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i64>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i64>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftl(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i64
! CHECK: %[[C_BITS:.*]] = arith.constant 64 : i64
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i64
! CHECK: %[[C_BITS_L:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i64
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_L]] : i64
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_L]] : i64
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[S_CONV]] : i64
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i64
! CHECK: %[[C_BITS_R:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i64
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_R]] : i64
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_R]] : i64
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[DIFF]] : i64
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i64
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i64
end subroutine dshiftl8_test
! CHECK-LABEL: dshiftl16_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i128>{{.*}}, %[[B:.*]]: !fir.ref<i128>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i128>{{.*}}
subroutine dshiftl16_test(a, b, s, c)
integer(kind=16) :: a, b
integer :: s
integer(kind=16) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i128>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i128>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftl(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i128
! CHECK: %[[C_BITS:.*]] = arith.constant 128 : i128
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i128
! CHECK: %[[C_BITS_L:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i128
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_L]] : i128
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_L]] : i128
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[S_CONV]] : i128
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i128
! CHECK: %[[C_BITS_R:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i128
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_R]] : i128
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_R]] : i128
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[DIFF]] : i128
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i128
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i128
end subroutine dshiftl16_test

View File

@ -0,0 +1,156 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: dshiftr1_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i8>{{.*}}, %[[B:.*]]: !fir.ref<i8>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i8>{{.*}}
subroutine dshiftr1_test(a, b, s, c)
integer(kind=1) :: a, b
integer :: s
integer(kind=1) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i8>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i8>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftr(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i8
! CHECK: %[[C_BITS:.*]] = arith.constant 8 : i8
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i8
! CHECK: %[[C_BITS_L:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i8
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_L]] : i8
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_L]] : i8
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[DIFF]] : i8
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i8
! CHECK: %[[C_BITS_R:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i8
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_R]] : i8
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_R]] : i8
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[S_CONV]] : i8
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i8
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i8
end subroutine dshiftr1_test
! CHECK-LABEL: dshiftr2_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i16>{{.*}}, %[[B:.*]]: !fir.ref<i16>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i16>{{.*}}
subroutine dshiftr2_test(a, b, s, c)
integer(kind=2) :: a, b
integer :: s
integer(kind=2) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i16>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i16>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftr(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i16
! CHECK: %[[C_BITS:.*]] = arith.constant 16 : i16
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i16
! CHECK: %[[C_BITS_L:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i16
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_L]] : i16
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_L]] : i16
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[DIFF]] : i16
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i16
! CHECK: %[[C_BITS_R:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i16
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_R]] : i16
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_R]] : i16
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[S_CONV]] : i16
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i16
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i16
end subroutine dshiftr2_test
! CHECK-LABEL: dshiftr4_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i32>{{.*}}
subroutine dshiftr4_test(a, b, s, c)
integer(kind=4) :: a, b
integer :: s
integer(kind=4) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftr(a, b, s)
! CHECK: %[[C_BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_VAL]] : i32
! CHECK: %[[C_BITS_L:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_L]] : i32
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_L]] : i32
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[DIFF]] : i32
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i32
! CHECK: %[[C_BITS_R:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[S_VAL]], %[[C_0_R]] : i32
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[S_VAL]], %[[C_BITS_R]] : i32
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[S_VAL]] : i32
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i32
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i32
end subroutine dshiftr4_test
! CHECK-LABEL: dshiftr8_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i64>{{.*}}, %[[B:.*]]: !fir.ref<i64>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i64>{{.*}}
subroutine dshiftr8_test(a, b, s, c)
integer(kind=8) :: a, b
integer :: s
integer(kind=8) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i64>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i64>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftr(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i64
! CHECK: %[[C_BITS:.*]] = arith.constant 64 : i64
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i64
! CHECK: %[[C_BITS_L:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i64
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_L]] : i64
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_L]] : i64
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[DIFF]] : i64
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i64
! CHECK: %[[C_BITS_R:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i64
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_R]] : i64
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_R]] : i64
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[S_CONV]] : i64
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i64
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i64
end subroutine dshiftr8_test
! CHECK-LABEL: dshiftr16_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i128>{{.*}}, %[[B:.*]]: !fir.ref<i128>{{.*}}, %[[S:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i128>{{.*}}
subroutine dshiftr16_test(a, b, s, c)
integer(kind=16) :: a, b
integer :: s
integer(kind=16) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i128>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i128>
! CHECK: %[[S_VAL:.*]] = fir.load %[[S]] : !fir.ref<i32>
c = dshiftr(a, b, s)
! CHECK: %[[S_CONV:.*]] = fir.convert %[[S_VAL]] : (i32) -> i128
! CHECK: %[[C_BITS:.*]] = arith.constant 128 : i128
! CHECK: %[[DIFF:.*]] = arith.subi %[[C_BITS]], %[[S_CONV]] : i128
! CHECK: %[[C_BITS_L:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0_L:.*]] = arith.constant 0 : i128
! CHECK: %[[UNDER_L:.*]] = arith.cmpi slt, %[[DIFF]], %[[C_0_L]] : i128
! CHECK: %[[OVER_L:.*]] = arith.cmpi sge, %[[DIFF]], %[[C_BITS_L]] : i128
! CHECK: %[[INV_L:.*]] = arith.ori %[[UNDER_L]], %[[OVER_L]] : i1
! CHECK: %[[SHL:.*]] = arith.shli %[[A_VAL]], %[[DIFF]] : i128
! CHECK: %[[LFT:.*]] = arith.select %[[INV_L]], %[[C_0_L]], %[[SHL]] : i128
! CHECK: %[[C_BITS_R:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0_R:.*]] = arith.constant 0 : i128
! CHECK: %[[UNDER_R:.*]] = arith.cmpi slt, %[[S_CONV]], %[[C_0_R]] : i128
! CHECK: %[[OVER_R:.*]] = arith.cmpi sge, %[[S_CONV]], %[[C_BITS_R]] : i128
! CHECK: %[[INV_R:.*]] = arith.ori %[[UNDER_R]], %[[OVER_R]] : i1
! CHECK: %[[SHR:.*]] = arith.shrui %[[B_VAL]], %[[S_CONV]] : i128
! CHECK: %[[RGT:.*]] = arith.select %[[INV_R]], %[[C_0_R]], %[[SHR]] : i128
! CHECK: %[[SHIFT:.*]] = arith.ori %[[LFT]], %[[RGT]] : i128
end subroutine dshiftr16_test

View File

@ -0,0 +1,101 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: shifta1_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i8>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i8>{{.*}}
subroutine shifta1_test(a, b, c)
integer(kind=1) :: a
integer :: b
integer(kind=1) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i8>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shifta(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0:.*]] = arith.constant 0 : i8
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i8
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i8
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i8
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrsi %[[A_VAL]], %[[B_CONV]] : i8
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i8
end subroutine shifta1_test
! CHECK-LABEL: shifta2_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i16>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i16>{{.*}}
subroutine shifta2_test(a, b, c)
integer(kind=2) :: a
integer :: b
integer(kind=2) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i16>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shifta(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0:.*]] = arith.constant 0 : i16
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i16
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i16
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i16
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrsi %[[A_VAL]], %[[B_CONV]] : i16
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i16
end subroutine shifta2_test
! CHECK-LABEL: shifta4_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i32>{{.*}}
subroutine shifta4_test(a, b, c)
integer(kind=4) :: a
integer :: b
integer(kind=4) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shifta(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_VAL]], %[[C_0]] : i32
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_VAL]], %[[C_BITS]] : i32
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrsi %[[A_VAL]], %[[B_VAL]] : i32
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i32
end subroutine shifta4_test
! CHECK-LABEL: shifta8_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i64>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i64>{{.*}}
subroutine shifta8_test(a, b, c)
integer(kind=8) :: a
integer :: b
integer(kind=8) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i64>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shifta(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0:.*]] = arith.constant 0 : i64
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i64
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i64
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i64
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrsi %[[A_VAL]], %[[B_CONV]] : i64
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i64
end subroutine shifta8_test
! CHECK-LABEL: shifta16_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i128>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i128>{{.*}}
subroutine shifta16_test(a, b, c)
integer(kind=16) :: a
integer :: b
integer(kind=16) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i128>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shifta(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0:.*]] = arith.constant 0 : i128
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i128
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i128
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i128
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrsi %[[A_VAL]], %[[B_CONV]] : i128
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i128
end subroutine shifta16_test

View File

@ -0,0 +1,101 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: shiftl1_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i8>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i8>{{.*}}
subroutine shiftl1_test(a, b, c)
integer(kind=1) :: a
integer :: b
integer(kind=1) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i8>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftl(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0:.*]] = arith.constant 0 : i8
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i8
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i8
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i8
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shli %[[A_VAL]], %[[B_CONV]] : i8
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i8
end subroutine shiftl1_test
! CHECK-LABEL: shiftl2_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i16>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i16>{{.*}}
subroutine shiftl2_test(a, b, c)
integer(kind=2) :: a
integer :: b
integer(kind=2) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i16>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftl(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0:.*]] = arith.constant 0 : i16
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i16
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i16
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i16
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shli %[[A_VAL]], %[[B_CONV]] : i16
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i16
end subroutine shiftl2_test
! CHECK-LABEL: shiftl4_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i32>{{.*}}
subroutine shiftl4_test(a, b, c)
integer(kind=4) :: a
integer :: b
integer(kind=4) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftl(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_VAL]], %[[C_0]] : i32
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_VAL]], %[[C_BITS]] : i32
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shli %[[A_VAL]], %[[B_VAL]] : i32
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i32
end subroutine shiftl4_test
! CHECK-LABEL: shiftl8_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i64>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i64>{{.*}}
subroutine shiftl8_test(a, b, c)
integer(kind=8) :: a
integer :: b
integer(kind=8) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i64>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftl(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0:.*]] = arith.constant 0 : i64
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i64
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i64
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i64
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shli %[[A_VAL]], %[[B_CONV]] : i64
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i64
end subroutine shiftl8_test
! CHECK-LABEL: shiftl16_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i128>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i128>{{.*}}
subroutine shiftl16_test(a, b, c)
integer(kind=16) :: a
integer :: b
integer(kind=16) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i128>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftl(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0:.*]] = arith.constant 0 : i128
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i128
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i128
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i128
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shli %[[A_VAL]], %[[B_CONV]] : i128
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i128
end subroutine shiftl16_test

View File

@ -0,0 +1,101 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: shiftr1_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i8>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i8>{{.*}}
subroutine shiftr1_test(a, b, c)
integer(kind=1) :: a
integer :: b
integer(kind=1) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i8>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftr(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 8 : i8
! CHECK: %[[C_0:.*]] = arith.constant 0 : i8
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i8
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i8
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i8
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrui %[[A_VAL]], %[[B_CONV]] : i8
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i8
end subroutine shiftr1_test
! CHECK-LABEL: shiftr2_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i16>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i16>{{.*}}
subroutine shiftr2_test(a, b, c)
integer(kind=2) :: a
integer :: b
integer(kind=2) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i16>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftr(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 16 : i16
! CHECK: %[[C_0:.*]] = arith.constant 0 : i16
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i16
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i16
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i16
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrui %[[A_VAL]], %[[B_CONV]] : i16
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i16
end subroutine shiftr2_test
! CHECK-LABEL: shiftr4_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i32>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i32>{{.*}}
subroutine shiftr4_test(a, b, c)
integer(kind=4) :: a
integer :: b
integer(kind=4) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftr(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 32 : i32
! CHECK: %[[C_0:.*]] = arith.constant 0 : i32
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_VAL]], %[[C_0]] : i32
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_VAL]], %[[C_BITS]] : i32
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrui %[[A_VAL]], %[[B_VAL]] : i32
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i32
end subroutine shiftr4_test
! CHECK-LABEL: shiftr8_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i64>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i64>{{.*}}
subroutine shiftr8_test(a, b, c)
integer(kind=8) :: a
integer :: b
integer(kind=8) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i64>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftr(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 64 : i64
! CHECK: %[[C_0:.*]] = arith.constant 0 : i64
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i64
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i64
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i64
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrui %[[A_VAL]], %[[B_CONV]] : i64
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i64
end subroutine shiftr8_test
! CHECK-LABEL: shiftr16_test
! CHECK-SAME: %[[A:.*]]: !fir.ref<i128>{{.*}}, %[[B:.*]]: !fir.ref<i32>{{.*}}, %[[C:.*]]: !fir.ref<i128>{{.*}}
subroutine shiftr16_test(a, b, c)
integer(kind=16) :: a
integer :: b
integer(kind=16) :: c
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i128>
! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
c = shiftr(a, b)
! CHECK: %[[C_BITS:.*]] = arith.constant 128 : i128
! CHECK: %[[C_0:.*]] = arith.constant 0 : i128
! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i32) -> i128
! CHECK: %[[UNDER:.*]] = arith.cmpi slt, %[[B_CONV]], %[[C_0]] : i128
! CHECK: %[[OVER:.*]] = arith.cmpi sge, %[[B_CONV]], %[[C_BITS]] : i128
! CHECK: %[[INVALID:.*]] = arith.ori %[[UNDER]], %[[OVER]] : i1
! CHECK: %[[SHIFT:.*]] = arith.shrui %[[A_VAL]], %[[B_CONV]] : i128
! CHECK: %[[RES:.*]] = arith.select %[[INVALID]], %[[C_0]], %[[SHIFT]] : i128
end subroutine shiftr16_test