@@ -1294,6 +1294,91 @@ mlir::LogicalResult CIRToLLVMCmpOpLowering::matchAndRewrite(
12941294 return mlir::success ();
12951295}
12961296
1297+ mlir::LogicalResult CIRToLLVMShiftOpLowering::matchAndRewrite (
1298+ cir::ShiftOp op, OpAdaptor adaptor,
1299+ mlir::ConversionPatternRewriter &rewriter) const {
1300+ auto cirAmtTy = mlir::dyn_cast<cir::IntType>(op.getAmount ().getType ());
1301+ auto cirValTy = mlir::dyn_cast<cir::IntType>(op.getValue ().getType ());
1302+
1303+ // Operands could also be vector type
1304+ assert (!cir::MissingFeatures::vectorType ());
1305+ mlir::Type llvmTy = getTypeConverter ()->convertType (op.getType ());
1306+ mlir::Value amt = adaptor.getAmount ();
1307+ mlir::Value val = adaptor.getValue ();
1308+
1309+ // TODO(cir): Assert for vector types
1310+ assert ((cirValTy && cirAmtTy) &&
1311+ " shift input type must be integer or vector type, otherwise NYI" );
1312+
1313+ assert ((cirValTy == op.getType ()) && " inconsistent operands' types NYI" );
1314+
1315+ // Ensure shift amount is the same type as the value. Some undefined
1316+ // behavior might occur in the casts below as per [C99 6.5.7.3].
1317+ // Vector type shift amount needs no cast as type consistency is expected to
1318+ // be already be enforced at CIRGen.
1319+ if (cirAmtTy)
1320+ amt = getLLVMIntCast (rewriter, amt, mlir::cast<mlir::IntegerType>(llvmTy),
1321+ !cirAmtTy.isSigned (), cirAmtTy.getWidth (),
1322+ cirValTy.getWidth ());
1323+
1324+ // Lower to the proper LLVM shift operation.
1325+ if (op.getIsShiftleft ()) {
1326+ rewriter.replaceOpWithNewOp <mlir::LLVM::ShlOp>(op, llvmTy, val, amt);
1327+ } else {
1328+ assert (!cir::MissingFeatures::vectorType ());
1329+ bool isUnsigned = !cirValTy.isSigned ();
1330+ if (isUnsigned)
1331+ rewriter.replaceOpWithNewOp <mlir::LLVM::LShrOp>(op, llvmTy, val, amt);
1332+ else
1333+ rewriter.replaceOpWithNewOp <mlir::LLVM::AShrOp>(op, llvmTy, val, amt);
1334+ }
1335+
1336+ return mlir::success ();
1337+ }
1338+
1339+ mlir::LogicalResult CIRToLLVMSelectOpLowering::matchAndRewrite (
1340+ cir::SelectOp op, OpAdaptor adaptor,
1341+ mlir::ConversionPatternRewriter &rewriter) const {
1342+ auto getConstantBool = [](mlir::Value value) -> std::optional<bool > {
1343+ auto definingOp =
1344+ mlir::dyn_cast_if_present<cir::ConstantOp>(value.getDefiningOp ());
1345+ if (!definingOp)
1346+ return std::nullopt ;
1347+
1348+ auto constValue = mlir::dyn_cast<cir::BoolAttr>(definingOp.getValue ());
1349+ if (!constValue)
1350+ return std::nullopt ;
1351+
1352+ return constValue.getValue ();
1353+ };
1354+
1355+ // Two special cases in the LLVMIR codegen of select op:
1356+ // - select %0, %1, false => and %0, %1
1357+ // - select %0, true, %1 => or %0, %1
1358+ if (mlir::isa<cir::BoolType>(op.getTrueValue ().getType ())) {
1359+ std::optional<bool > trueValue = getConstantBool (op.getTrueValue ());
1360+ std::optional<bool > falseValue = getConstantBool (op.getFalseValue ());
1361+ if (falseValue.has_value () && !*falseValue) {
1362+ // select %0, %1, false => and %0, %1
1363+ rewriter.replaceOpWithNewOp <mlir::LLVM::AndOp>(op, adaptor.getCondition (),
1364+ adaptor.getTrueValue ());
1365+ return mlir::success ();
1366+ }
1367+ if (trueValue.has_value () && *trueValue) {
1368+ // select %0, true, %1 => or %0, %1
1369+ rewriter.replaceOpWithNewOp <mlir::LLVM::OrOp>(op, adaptor.getCondition (),
1370+ adaptor.getFalseValue ());
1371+ return mlir::success ();
1372+ }
1373+ }
1374+
1375+ mlir::Value llvmCondition = adaptor.getCondition ();
1376+ rewriter.replaceOpWithNewOp <mlir::LLVM::SelectOp>(
1377+ op, llvmCondition, adaptor.getTrueValue (), adaptor.getFalseValue ());
1378+
1379+ return mlir::success ();
1380+ }
1381+
12971382static void prepareTypeConverter (mlir::LLVMTypeConverter &converter,
12981383 mlir::DataLayout &dataLayout) {
12991384 converter.addConversion ([&](cir::PointerType type) -> mlir::Type {
@@ -1439,6 +1524,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
14391524 CIRToLLVMConstantOpLowering,
14401525 CIRToLLVMFuncOpLowering,
14411526 CIRToLLVMGetGlobalOpLowering,
1527+ CIRToLLVMSelectOpLowering,
1528+ CIRToLLVMShiftOpLowering,
14421529 CIRToLLVMTrapOpLowering,
14431530 CIRToLLVMUnaryOpLowering
14441531 // clang-format on
0 commit comments