[PATCH] D140087: [X86] Replace (31/63 -/^ X) with (NOT X) and ignore (32/64 ^ X) when computing shift count
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 29 08:08:12 PST 2022
goldstein.w.n added a comment.
In D140087#4019429 <https://reviews.llvm.org/D140087#4019429>, @lebedev.ri wrote:
> Alive2 doesn't deal with assembly/dag, only ir.
> I'm asking you to write the proofs for these changes via an IR tests,
> explicitly modelling the implicit modulo of the shift amount, which isn't a thing in IR.
I see. Sorry about that. How about the following:
in.ll:
define i32 @foo32_(i32 %val, i32 %cnt) {
%adjcnt = sub i32 31, %cnt
%result = shl i32 %val, %adjcnt
ret i32 %result
}
define i32 @foo32_2(i32 %val, i32 %cnt) {
%adjcnt = xor i32 31, %cnt
%result = shl i32 %val, %adjcnt
ret i32 %result
}
define i32 @foo32_3(i32 %val, i32 %cnt) {
%adjcnt = xor i32 32, %cnt
%result = shl i32 %val, %adjcnt
ret i32 %result
}
define i64 @foo64_(i64 %val, i64 %cnt) {
%adjcnt = sub i64 63, %cnt
%result = shl i64 %val, %adjcnt
ret i64 %result
}
define i64 @foo64_2(i64 %val, i64 %cnt) {
%adjcnt = xor i64 63, %cnt
%result = shl i64 %val, %adjcnt
ret i64 %result
}
define i64 @foo64_3(i64 %val, i64 %cnt) {
%adjcnt = xor i64 64, %cnt
%result = shl i64 %val, %adjcnt
ret i64 %result
}
out.ll
define i32 @foo32_(i32 %val, i32 %cnt) {
%adjcnt = xor i32 -1, %cnt
%shiftcnt = and i32 31, %adjcnt
%result = shl i32 %val, %shiftcnt
ret i32 %result
}
define i32 @foo32_2(i32 %val, i32 %cnt) {
%adjcnt = xor i32 -1, %cnt
%shiftcnt = and i32 31, %adjcnt
%result = shl i32 %val, %shiftcnt
ret i32 %result
}
define i32 @foo32_3(i32 %val, i32 %cnt) {
%shiftcnt = and i32 31, %cnt
%result = shl i32 %val, %shiftcnt
ret i32 %result
}
define i64 @foo64_(i64 %val, i64 %cnt) {
%adjcnt = xor i64 -1, %cnt
%shiftcnt = and i64 63, %adjcnt
%result = shl i64 %val, %shiftcnt
ret i64 %result
}
define i64 @foo64_2(i64 %val, i64 %cnt) {
%adjcnt = xor i64 -1, %cnt
%shiftcnt = and i64 63, %adjcnt
%result = shl i64 %val, %shiftcnt
ret i64 %result
}
define i64 @foo64_3(i64 %val, i64 %cnt) {
%shiftcnt = and i64 63, %cnt
%result = shl i64 %val, %shiftcnt
ret i64 %result
}
Running:
$> /home/noah/programs/opensource/llvm-dev/src/alive2/build/alive-tv in.ll out.ll
----------------------------------------
define i32 @foo32_(i32 %val, i32 %cnt) {
%0:
%adjcnt = sub i32 31, %cnt
%result = shl i32 %val, %adjcnt
ret i32 %result
}
=>
define i32 @foo32_(i32 %val, i32 %cnt) {
%0:
%adjcnt = xor i32 4294967295, %cnt
%shiftcnt = and i32 31, %adjcnt
%result = shl i32 %val, %shiftcnt
ret i32 %result
}
Transformation seems to be correct!
----------------------------------------
define i32 @foo32_2(i32 %val, i32 %cnt) {
%0:
%adjcnt = xor i32 31, %cnt
%result = shl i32 %val, %adjcnt
ret i32 %result
}
=>
define i32 @foo32_2(i32 %val, i32 %cnt) {
%0:
%adjcnt = xor i32 4294967295, %cnt
%shiftcnt = and i32 31, %adjcnt
%result = shl i32 %val, %shiftcnt
ret i32 %result
}
Transformation seems to be correct!
----------------------------------------
define i32 @foo32_3(i32 %val, i32 %cnt) {
%0:
%adjcnt = xor i32 32, %cnt
%result = shl i32 %val, %adjcnt
ret i32 %result
}
=>
define i32 @foo32_3(i32 %val, i32 %cnt) {
%0:
%shiftcnt = and i32 31, %cnt
%result = shl i32 %val, %shiftcnt
ret i32 %result
}
Transformation seems to be correct!
----------------------------------------
define i64 @foo64_(i64 %val, i64 %cnt) {
%0:
%adjcnt = sub i64 63, %cnt
%result = shl i64 %val, %adjcnt
ret i64 %result
}
=>
define i64 @foo64_(i64 %val, i64 %cnt) {
%0:
%adjcnt = xor i64 -1, %cnt
%shiftcnt = and i64 63, %adjcnt
%result = shl i64 %val, %shiftcnt
ret i64 %result
}
Transformation seems to be correct!
----------------------------------------
define i64 @foo64_2(i64 %val, i64 %cnt) {
%0:
%adjcnt = xor i64 63, %cnt
%result = shl i64 %val, %adjcnt
ret i64 %result
}
=>
define i64 @foo64_2(i64 %val, i64 %cnt) {
%0:
%adjcnt = xor i64 -1, %cnt
%shiftcnt = and i64 63, %adjcnt
%result = shl i64 %val, %shiftcnt
ret i64 %result
}
Transformation seems to be correct!
----------------------------------------
define i64 @foo64_3(i64 %val, i64 %cnt) {
%0:
%adjcnt = xor i64 64, %cnt
%result = shl i64 %val, %adjcnt
ret i64 %result
}
=>
define i64 @foo64_3(i64 %val, i64 %cnt) {
%0:
%shiftcnt = and i64 63, %cnt
%result = shl i64 %val, %shiftcnt
ret i64 %result
}
Transformation seems to be correct!
Summary:
6 correct transformations
0 incorrect transformations
0 failed-to-prove transformations
0 Alive2 errors
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D140087/new/
https://reviews.llvm.org/D140087
More information about the llvm-commits
mailing list