Skip to content

Simplify (some) big concats#599

Merged
agle merged 3 commits intomainfrom
concat-simp
Feb 6, 2026
Merged

Simplify (some) big concats#599
agle merged 3 commits intomainfrom
concat-simp

Conversation

@b-paul
Copy link
Contributor

@b-paul b-paul commented Feb 5, 2026

You may have seen expressions like the following (using boogie syntax):

bvor32(bvand32((((((((((((((((((((((((((((((((bvlshr32(#R19_1209[32:0], 31bv32)[1:0] ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]) ++ bvlshr32(#R19_1209[32:0], 31bv32)[1:0]), 4227858432bv32), bvand32(bvor32(bvand32(bvor32(bvlshr32(#R19_1209[32:0], 6bv32), bvshl32(#R19_1209[32:0], 26bv32)), 4294967295bv32), 0bv32), 67108863bv32))

This is taken from main in cntlm. If we look closely, this is just a concatenation of the same singular bit over and over again! We could just replace it with a repeat.

bvor32(bvand32(repeat32_1(bvlshr32(#R19_1209[32:0], 31bv32)[1:0]), 4227858432bv32), bvand32(bvor32(bvand32(bvor32(bvlshr32(#R19_1209[32:0], 6bv32), bvshl32(#R19_1209[32:0], 26bv32)), 4294967295bv32), 0bv32), 67108863bv32))

But if you think about it, a repeat of a one bit value is the same thing as a sign extend.

bvor32(bvand32(sign_extend31_1(bvlshr32(#R19_1209[32:0], 31bv32)[1:0]), 4227858432bv32), bvand32(bvor32(bvand32(bvor32(bvlshr32(#R19_1209[32:0], 6bv32), bvshl32(#R19_1209[32:0], 26bv32)), 4294967295bv32), 0bv32), 67108863bv32))

But if you think about it even more, we're doing a logical right shift by 31 then taking the first bit, and then sign extending... That's just an arithmetic right shift!

bvor32(bvand32(bvashr32(#R19_1209[32:0], 31bv32), 4227858432bv32), bvand32(bvor32(bvand32(bvor32(bvlshr32(#R19_1209[32:0], 6bv32), bvshl32(#R19_1209[32:0], 26bv32)), 4294967295bv32), 0bv32), 67108863bv32))

I suspect that these big concat chain comes from somewhere in the lifting pipeline not knowing how to handle 32 bit arithmetic shifts nicely. Hopefully the simplification helps somewhere!

@agle agle merged commit de7f516 into main Feb 6, 2026
12 checks passed
@agle agle deleted the concat-simp branch February 6, 2026 06:24
@agle agle mentioned this pull request Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants