@@ -73,6 +73,7 @@ Type adaptIntegralTypeSignedness(Type ty, bool needsUnsigned) {
73
73
74
74
// / Insert a cast operation to type \p ty if \p val does not have this type.
75
75
Value adaptValueType (Value val, ConversionPatternRewriter &rewriter, Type ty) {
76
+ assert (emitc::isSupportedEmitCType (val.getType ()));
76
77
return rewriter.createOrFold <emitc::CastOp>(val.getLoc (), ty, val);
77
78
}
78
79
@@ -279,7 +280,8 @@ class CmpIOpConversion : public OpConversionPattern<arith::CmpIOp> {
279
280
ConversionPatternRewriter &rewriter) const override {
280
281
281
282
Type type = adaptor.getLhs ().getType ();
282
- if (!type || !(isa<IntegerType>(type) || emitc::isPointerWideType (type))) {
283
+ if (!type || !(emitc::isIntegerOrOpaqueType (type) ||
284
+ emitc::isPointerWideType (type))) {
283
285
return rewriter.notifyMatchFailure (
284
286
op, " expected integer or size_t/ssize_t/ptrdiff_t type" );
285
287
}
@@ -334,7 +336,7 @@ class CastConversion : public OpConversionPattern<ArithOp> {
334
336
ConversionPatternRewriter &rewriter) const override {
335
337
336
338
Type opReturnType = this ->getTypeConverter ()->convertType (op.getType ());
337
- if (!opReturnType || !(isa<IntegerType> (opReturnType) ||
339
+ if (!opReturnType || !(emitc::isIntegerOrOpaqueType (opReturnType) ||
338
340
emitc::isPointerWideType (opReturnType)))
339
341
return rewriter.notifyMatchFailure (
340
342
op, " expected integer or size_t/ssize_t/ptrdiff_t result type" );
@@ -345,7 +347,7 @@ class CastConversion : public OpConversionPattern<ArithOp> {
345
347
}
346
348
347
349
Type operandType = adaptor.getIn ().getType ();
348
- if (!operandType || !(isa<IntegerType> (operandType) ||
350
+ if (!operandType || !(emitc::isIntegerOrOpaqueType (operandType) ||
349
351
emitc::isPointerWideType (operandType)))
350
352
return rewriter.notifyMatchFailure (
351
353
op, " expected integer or size_t/ssize_t/ptrdiff_t operand type" );
@@ -439,16 +441,17 @@ class BinaryUIOpConversion final : public OpConversionPattern<ArithOp> {
439
441
if (!newRetTy)
440
442
return rewriter.notifyMatchFailure (uiBinOp,
441
443
" converting result type failed" );
442
- if (!isa<IntegerType>(newRetTy)) {
444
+
445
+ if (!emitc::isIntegerOrOpaqueType (newRetTy)) {
443
446
return rewriter.notifyMatchFailure (uiBinOp, " expected integer type" );
444
447
}
445
448
Type unsignedType =
446
449
adaptIntegralTypeSignedness (newRetTy, /* needsUnsigned=*/ true );
447
450
if (!unsignedType)
448
451
return rewriter.notifyMatchFailure (uiBinOp,
449
452
" converting result type failed" );
450
- Value lhsAdapted = adaptValueType (uiBinOp .getLhs (), rewriter, unsignedType);
451
- Value rhsAdapted = adaptValueType (uiBinOp .getRhs (), rewriter, unsignedType);
453
+ Value lhsAdapted = adaptValueType (adaptor .getLhs (), rewriter, unsignedType);
454
+ Value rhsAdapted = adaptValueType (adaptor .getRhs (), rewriter, unsignedType);
452
455
453
456
auto newDivOp =
454
457
rewriter.create <EmitCOp>(uiBinOp.getLoc (), unsignedType,
@@ -469,7 +472,8 @@ class IntegerOpConversion final : public OpConversionPattern<ArithOp> {
469
472
ConversionPatternRewriter &rewriter) const override {
470
473
471
474
Type type = this ->getTypeConverter ()->convertType (op.getType ());
472
- if (!type || !(isa<IntegerType>(type) || emitc::isPointerWideType (type))) {
475
+ if (!type || !(emitc::isIntegerOrOpaqueType (type) ||
476
+ emitc::isPointerWideType (type))) {
473
477
return rewriter.notifyMatchFailure (
474
478
op, " expected integer or size_t/ssize_t/ptrdiff_t type" );
475
479
}
@@ -512,7 +516,7 @@ class BitwiseOpConversion : public OpConversionPattern<ArithOp> {
512
516
ConversionPatternRewriter &rewriter) const override {
513
517
514
518
Type type = this ->getTypeConverter ()->convertType (op.getType ());
515
- if (!isa_and_nonnull<IntegerType> (type)) {
519
+ if (!type || ! emitc::isIntegerOrOpaqueType (type)) {
516
520
return rewriter.notifyMatchFailure (
517
521
op,
518
522
" expected integer type, vector/tensor support not yet implemented" );
@@ -552,7 +556,9 @@ class ShiftOpConversion : public OpConversionPattern<ArithOp> {
552
556
ConversionPatternRewriter &rewriter) const override {
553
557
554
558
Type type = this ->getTypeConverter ()->convertType (op.getType ());
555
- if (!type || !(isa<IntegerType>(type) || emitc::isPointerWideType (type))) {
559
+ bool retIsOpaque = isa_and_nonnull<emitc::OpaqueType>(type);
560
+ if (!type || (!retIsOpaque && !(isa<IntegerType>(type) ||
561
+ emitc::isPointerWideType (type)))) {
556
562
return rewriter.notifyMatchFailure (
557
563
op, " expected integer or size_t/ssize_t/ptrdiff_t type" );
558
564
}
@@ -578,21 +584,33 @@ class ShiftOpConversion : public OpConversionPattern<ArithOp> {
578
584
op.getLoc (), rhsType, " sizeof" , ArrayRef<Value>{eight});
579
585
width = rewriter.create <emitc::MulOp>(op.getLoc (), rhsType, eight,
580
586
sizeOfCall.getResult (0 ));
581
- } else {
587
+ } else if (!retIsOpaque) {
582
588
width = rewriter.create <emitc::ConstantOp>(
583
589
op.getLoc (), rhsType,
584
590
rewriter.getIntegerAttr (rhsType, type.getIntOrFloatBitWidth ()));
591
+ } else {
592
+ width = rewriter.create <emitc::ConstantOp>(
593
+ op.getLoc (), rhsType,
594
+ emitc::OpaqueAttr::get (rhsType.getContext (),
595
+ " opaque_shift_bitwidth" ));
585
596
}
586
597
587
598
Value excessCheck = rewriter.create <emitc::CmpOp>(
588
599
op.getLoc (), rewriter.getI1Type (), emitc::CmpPredicate::lt, rhs, width);
589
600
590
601
// Any concrete value is a valid refinement of poison.
591
- Value poison = rewriter.create <emitc::ConstantOp>(
592
- op.getLoc (), arithmeticType,
593
- (isa<IntegerType>(arithmeticType)
594
- ? rewriter.getIntegerAttr (arithmeticType, 0 )
595
- : rewriter.getIndexAttr (0 )));
602
+ Value poison;
603
+ if (retIsOpaque) {
604
+ poison = rewriter.create <emitc::ConstantOp>(
605
+ op.getLoc (), arithmeticType,
606
+ emitc::OpaqueAttr::get (rhsType.getContext (), " opaque_shift_poison" ));
607
+ } else {
608
+ poison = rewriter.create <emitc::ConstantOp>(
609
+ op.getLoc (), arithmeticType,
610
+ (isa<IntegerType>(arithmeticType)
611
+ ? rewriter.getIntegerAttr (arithmeticType, 0 )
612
+ : rewriter.getIndexAttr (0 )));
613
+ }
596
614
597
615
emitc::ExpressionOp ternary = rewriter.create <emitc::ExpressionOp>(
598
616
op.getLoc (), arithmeticType, /* do_not_inline=*/ false );
@@ -669,19 +687,23 @@ class FtoICastOpConversion : public OpConversionPattern<CastOp> {
669
687
if (!dstType)
670
688
return rewriter.notifyMatchFailure (castOp, " type conversion failed" );
671
689
690
+ Type actualResultType = dstType;
691
+
672
692
// Float-to-i1 casts are not supported: any value with 0 < value < 1 must be
673
693
// truncated to 0, whereas a boolean conversion would return true.
674
- if (!emitc::isSupportedIntegerType (dstType) || dstType.isInteger (1 ))
675
- return rewriter.notifyMatchFailure (castOp,
676
- " unsupported cast destination type" );
677
-
678
- // Convert to unsigned if it's the "ui" variant
679
- // Signless is interpreted as signed, so no need to cast for "si"
680
- Type actualResultType = dstType;
681
- if (isa<arith::FPToUIOp>(castOp)) {
682
- actualResultType =
683
- rewriter.getIntegerType (dstType.getIntOrFloatBitWidth (),
684
- /* isSigned=*/ false );
694
+ bool dstIsOpaque = isa<emitc::OpaqueType>(dstType);
695
+ if (!dstIsOpaque) {
696
+ if (!emitc::isSupportedIntegerType (dstType) || dstType.isInteger (1 ))
697
+ return rewriter.notifyMatchFailure (castOp,
698
+ " unsupported cast destination type" );
699
+
700
+ // Convert to unsigned if it's the "ui" variant
701
+ // Signless is interpreted as signed, so no need to cast for "si"
702
+ if (isa<arith::FPToUIOp>(castOp)) {
703
+ actualResultType =
704
+ rewriter.getIntegerType (dstType.getIntOrFloatBitWidth (),
705
+ /* isSigned=*/ false );
706
+ }
685
707
}
686
708
687
709
Value result = rewriter.create <emitc::CastOp>(
@@ -708,7 +730,9 @@ class ItoFCastOpConversion : public OpConversionPattern<CastOp> {
708
730
ConversionPatternRewriter &rewriter) const override {
709
731
// Vectors in particular are not supported
710
732
Type operandType = adaptor.getIn ().getType ();
711
- if (!emitc::isSupportedIntegerType (operandType))
733
+ bool opIsOpaque = isa<emitc::OpaqueType>(operandType);
734
+
735
+ if (!(opIsOpaque || emitc::isSupportedIntegerType (operandType)))
712
736
return rewriter.notifyMatchFailure (castOp,
713
737
" unsupported cast source type" );
714
738
@@ -723,7 +747,7 @@ class ItoFCastOpConversion : public OpConversionPattern<CastOp> {
723
747
// Convert to unsigned if it's the "ui" variant
724
748
// Signless is interpreted as signed, so no need to cast for "si"
725
749
Type actualOperandType = operandType;
726
- if (isa<arith::UIToFPOp>(castOp)) {
750
+ if (!opIsOpaque && isa<arith::UIToFPOp>(castOp)) {
727
751
actualOperandType =
728
752
rewriter.getIntegerType (operandType.getIntOrFloatBitWidth (),
729
753
/* isSigned=*/ false );
@@ -751,7 +775,7 @@ class FpCastOpConversion : public OpConversionPattern<CastOp> {
751
775
ConversionPatternRewriter &rewriter) const override {
752
776
// Vectors in particular are not supported.
753
777
Type operandType = adaptor.getIn ().getType ();
754
- if (!emitc::isSupportedFloatType (operandType))
778
+ if (!emitc::isFloatOrOpaqueType (operandType))
755
779
return rewriter.notifyMatchFailure (castOp,
756
780
" unsupported cast source type" );
757
781
if (auto roundingModeOp =
@@ -765,7 +789,7 @@ class FpCastOpConversion : public OpConversionPattern<CastOp> {
765
789
if (!dstType)
766
790
return rewriter.notifyMatchFailure (castOp, " type conversion failed" );
767
791
768
- if (!emitc::isSupportedFloatType (dstType))
792
+ if (!emitc::isFloatOrOpaqueType (dstType))
769
793
return rewriter.notifyMatchFailure (castOp,
770
794
" unsupported cast destination type" );
771
795
0 commit comments