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>);
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,
{{{"vector_a", asBox}, {"vector_b", asBox}}},
/*isElemental=*/false},
{"dprod", &I::genDprod},
+ {"dshiftl", &I::genDshiftl},
+ {"dshiftr", &I::genDshiftr},
{"eoshift",
&I::genEoshift,
{{{"array", asBox},
{"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,
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,
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) {
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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