Skip to content

Commit a0dd8b3

Browse files
authored
[Cranelift] fold bnot+iadd (#13201)
1 parent ad2f37e commit a0dd8b3

3 files changed

Lines changed: 57 additions & 1 deletion

File tree

cranelift/codegen/src/opts/cprop.isle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,8 @@
457457
(decl ieee128_constant (Ieee128) Constant)
458458
(extern constructor ieee128_constant ieee128_constant)
459459
(extern extractor ieee128_constant ieee128_constant_extractor)
460+
461+
;; a special case of ~a = -a - 1
462+
;; ~(x + y) = -(x + y) - 1 = (~x) - y = (~x) + (-y)
463+
;; bnot pushed to the leaf so that it not only canonicalzes the IR but also folds the constant y into -y
464+
(rule (simplify (bnot (fits_in_64 ty) (iadd ty x (iconst ty y)))) (iadd ty (bnot ty x) (iconst ty (imm64_neg ty y))))

cranelift/filetests/filetests/egraph/arithmetic.clif

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,28 @@ block0(v0: i32):
439439
; return v6
440440
}
441441

442+
;; ~(x + y) --> (~x) + (-y)
443+
function %bnot_iadd_const_i32(i32) -> i32 {
444+
block0(v0: i32):
445+
v1 = iconst.i32 5
446+
v2 = iadd v0, v1
447+
v3 = bnot v2
448+
return v3
449+
; check: v4 = bnot v0
450+
; check: v5 = iconst.i32 -5
451+
; check: v6 = iadd v4, v5
452+
; check: return v6
453+
}
454+
455+
;; ~(x + y) --> (~x) + (-y)
456+
function %bnot_iadd_neg_const_i64(i64) -> i64 {
457+
block0(v0: i64):
458+
v1 = iconst.i64 -7
459+
v2 = iadd v0, v1
460+
v3 = bnot v2
461+
return v3
462+
; check: v4 = bnot v0
463+
; check: v5 = iconst.i64 7
464+
; check: v6 = iadd v4, v5
465+
; check: return v6
466+
}

cranelift/filetests/filetests/runtests/arithmetic.clif

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,4 +1038,30 @@ block0(v0: i32, v1: i32):
10381038
}
10391039

10401040
; run: %test_ugt_x_umax(0, 0) == 0
1041-
; run: %test_ugt_x_umax(1, 2) == 0
1041+
; run: %test_ugt_x_umax(1, 2) == 0
1042+
1043+
function %fold_bnot_iadd_const_i32_rt(i32) -> i32 fast {
1044+
block0(v0: i32):
1045+
v1 = iconst.i32 5
1046+
v2 = iadd v0, v1
1047+
v3 = bnot v2
1048+
return v3
1049+
}
1050+
1051+
; run: %fold_bnot_iadd_const_i32_rt(0) == -6
1052+
; run: %fold_bnot_iadd_const_i32_rt(7) == -13
1053+
; run: %fold_bnot_iadd_const_i32_rt(-5) == -1
1054+
; run: %fold_bnot_iadd_const_i32_rt(0x7fffffff) == 0x7ffffffb
1055+
1056+
function %fold_bnot_iadd_neg_const_i64_rt(i64) -> i64 fast {
1057+
block0(v0: i64):
1058+
v1 = iconst.i64 -7
1059+
v2 = iadd v0, v1
1060+
v3 = bnot v2
1061+
return v3
1062+
}
1063+
1064+
; run: %fold_bnot_iadd_neg_const_i64_rt(0) == 6
1065+
; run: %fold_bnot_iadd_neg_const_i64_rt(7) == -1
1066+
; run: %fold_bnot_iadd_neg_const_i64_rt(-1) == 7
1067+
; run: %fold_bnot_iadd_neg_const_i64_rt(0x80000000_00000000) == 0x80000000_00000006

0 commit comments

Comments
 (0)