File tree Expand file tree Collapse file tree 2 files changed +44
-2
lines changed Expand file tree Collapse file tree 2 files changed +44
-2
lines changed Original file line number Diff line number Diff line change @@ -588,8 +588,31 @@ static SILValue constantFoldBinary(BuiltinInst *BI,
588588 // Are there valid uses for these in stdlib?
589589 case BuiltinValueKind::Add:
590590 case BuiltinValueKind::Mul:
591- case BuiltinValueKind::Sub:
592- return nullptr ;
591+ case BuiltinValueKind::Sub: {
592+ OperandValueArrayRef Args = BI->getArguments ();
593+ auto *LHS = dyn_cast<IntegerLiteralInst>(Args[0 ]);
594+ auto *RHS = dyn_cast<IntegerLiteralInst>(Args[1 ]);
595+ if (!RHS || !LHS)
596+ return nullptr ;
597+ APInt LHSI = LHS->getValue ();
598+ APInt RHSI = RHS->getValue ();
599+
600+ switch (ID) {
601+ default : llvm_unreachable (" Not all cases are covered!" );
602+ case BuiltinValueKind::Add:
603+ LHSI += RHSI;
604+ break ;
605+ case BuiltinValueKind::Mul:
606+ LHSI *= RHSI;
607+ break ;
608+ case BuiltinValueKind::Sub:
609+ LHSI -= RHSI;
610+ break ;
611+ }
612+
613+ SILBuilderWithScope B (BI);
614+ return B.createIntegerLiteral (BI->getLoc (), BI->getType (), LHSI);
615+ }
593616
594617 case BuiltinValueKind::And:
595618 case BuiltinValueKind::AShr:
Original file line number Diff line number Diff line change @@ -102,6 +102,25 @@ bb0:
102102// CHECK-NEXT: return [[RES]] : $Builtin.Int64
103103}
104104
105+ // Compute an expression using a chain of arithmetic with non-overflowing instructions: 2 * (2 + 3) - 3
106+ sil @fold_arithmetic_without_overflow : $@convention(thin) () -> Builtin.Int64 {
107+ bb0:
108+ %0 = integer_literal $Builtin.Int64, 2
109+ %110 = integer_literal $Builtin.Int64, 3
110+ %19 = builtin "add_Int64"(%0 : $Builtin.Int64, %110 : $Builtin.Int64) : $Builtin.Int64
111+ %21 = builtin "mul_Int64"(%0 : $Builtin.Int64, %19 : $Builtin.Int64) : $Builtin.Int64
112+ %23 = builtin "sub_Int64"(%21 : $Builtin.Int64, %110 : $Builtin.Int64) : $Builtin.Int64
113+ return %23 : $Builtin.Int64
114+
115+ // CHECK-LABEL: sil @fold_arithmetic_without_overflow
116+ // CHECK-NOT: integer_literal $Builtin.Int64, 2
117+ // CHECK-NOT: integer_literal $Builtin.Int64, 3
118+ // CHECK-NOT: integer_literal $Builtin.Int64, 0
119+ // CHECK-NOT: builtin
120+ // CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 7
121+ // CHECK-NEXT: return [[RES]] : $Builtin.Int64
122+ }
123+
105124// Fold casts. (This test assumes that DCE does not run, otherwise the unreachable blocks will get removed.)
106125sil @fold_trunc : $@convention(thin) () -> Builtin.Int64 {
107126bb0:
You can’t perform that action at this time.
0 commit comments