@@ -1117,6 +1117,91 @@ mlir::LogicalResult CIRToLLVMBinOpLowering::matchAndRewrite(
11171117 return mlir::LogicalResult::success ();
11181118}
11191119
1120+ mlir::LogicalResult CIRToLLVMShiftOpLowering::matchAndRewrite (
1121+ cir::ShiftOp op, OpAdaptor adaptor,
1122+ mlir::ConversionPatternRewriter &rewriter) const {
1123+ auto cirAmtTy = mlir::dyn_cast<cir::IntType>(op.getAmount ().getType ());
1124+ auto cirValTy = mlir::dyn_cast<cir::IntType>(op.getValue ().getType ());
1125+
1126+ // Operands could also be vector type
1127+ assert (!cir::MissingFeatures::vectorType ());
1128+ mlir::Type llvmTy = getTypeConverter ()->convertType (op.getType ());
1129+ mlir::Value amt = adaptor.getAmount ();
1130+ mlir::Value val = adaptor.getValue ();
1131+
1132+ // TODO(cir): Assert for vector types
1133+ assert ((cirValTy && cirAmtTy) &&
1134+ " shift input type must be integer or vector type, otherwise NYI" );
1135+
1136+ assert ((cirValTy == op.getType ()) && " inconsistent operands' types NYI" );
1137+
1138+ // Ensure shift amount is the same type as the value. Some undefined
1139+ // behavior might occur in the casts below as per [C99 6.5.7.3].
1140+ // Vector type shift amount needs no cast as type consistency is expected to
1141+ // be already be enforced at CIRGen.
1142+ if (cirAmtTy)
1143+ amt = getLLVMIntCast (rewriter, amt, mlir::cast<mlir::IntegerType>(llvmTy),
1144+ !cirAmtTy.isSigned (), cirAmtTy.getWidth (),
1145+ cirValTy.getWidth ());
1146+
1147+ // Lower to the proper LLVM shift operation.
1148+ if (op.getIsShiftleft ()) {
1149+ rewriter.replaceOpWithNewOp <mlir::LLVM::ShlOp>(op, llvmTy, val, amt);
1150+ } else {
1151+ assert (!cir::MissingFeatures::vectorType ());
1152+ bool isUnsigned = !cirValTy.isSigned ();
1153+ if (isUnsigned)
1154+ rewriter.replaceOpWithNewOp <mlir::LLVM::LShrOp>(op, llvmTy, val, amt);
1155+ else
1156+ rewriter.replaceOpWithNewOp <mlir::LLVM::AShrOp>(op, llvmTy, val, amt);
1157+ }
1158+
1159+ return mlir::success ();
1160+ }
1161+
1162+ mlir::LogicalResult CIRToLLVMSelectOpLowering::matchAndRewrite (
1163+ cir::SelectOp op, OpAdaptor adaptor,
1164+ mlir::ConversionPatternRewriter &rewriter) const {
1165+ auto getConstantBool = [](mlir::Value value) -> std::optional<bool > {
1166+ auto definingOp =
1167+ mlir::dyn_cast_if_present<cir::ConstantOp>(value.getDefiningOp ());
1168+ if (!definingOp)
1169+ return std::nullopt ;
1170+
1171+ auto constValue = mlir::dyn_cast<cir::BoolAttr>(definingOp.getValue ());
1172+ if (!constValue)
1173+ return std::nullopt ;
1174+
1175+ return constValue.getValue ();
1176+ };
1177+
1178+ // Two special cases in the LLVMIR codegen of select op:
1179+ // - select %0, %1, false => and %0, %1
1180+ // - select %0, true, %1 => or %0, %1
1181+ if (mlir::isa<cir::BoolType>(op.getTrueValue ().getType ())) {
1182+ std::optional<bool > trueValue = getConstantBool (op.getTrueValue ());
1183+ std::optional<bool > falseValue = getConstantBool (op.getFalseValue ());
1184+ if (falseValue.has_value () && !*falseValue) {
1185+ // select %0, %1, false => and %0, %1
1186+ rewriter.replaceOpWithNewOp <mlir::LLVM::AndOp>(op, adaptor.getCondition (),
1187+ adaptor.getTrueValue ());
1188+ return mlir::success ();
1189+ }
1190+ if (trueValue.has_value () && *trueValue) {
1191+ // select %0, true, %1 => or %0, %1
1192+ rewriter.replaceOpWithNewOp <mlir::LLVM::OrOp>(op, adaptor.getCondition (),
1193+ adaptor.getFalseValue ());
1194+ return mlir::success ();
1195+ }
1196+ }
1197+
1198+ mlir::Value llvmCondition = adaptor.getCondition ();
1199+ rewriter.replaceOpWithNewOp <mlir::LLVM::SelectOp>(
1200+ op, llvmCondition, adaptor.getTrueValue (), adaptor.getFalseValue ());
1201+
1202+ return mlir::success ();
1203+ }
1204+
11201205static void prepareTypeConverter (mlir::LLVMTypeConverter &converter,
11211206 mlir::DataLayout &dataLayout) {
11221207 converter.addConversion ([&](cir::PointerType type) -> mlir::Type {
@@ -1259,6 +1344,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
12591344 CIRToLLVMBrCondOpLowering,
12601345 CIRToLLVMBrOpLowering,
12611346 CIRToLLVMFuncOpLowering,
1347+ CIRToLLVMSelectOpLowering,
1348+ CIRToLLVMShiftOpLowering,
12621349 CIRToLLVMTrapOpLowering,
12631350 CIRToLLVMUnaryOpLowering
12641351 // clang-format on
0 commit comments