Skip to content

Instantly share code, notes, and snippets.

@chfast
Created March 23, 2016 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chfast/1a6421ba8de03cc08c52 to your computer and use it in GitHub Desktop.
Save chfast/1a6421ba8de03cc08c52 to your computer and use it in GitHub Desktop.
Shrinking arithmetic in LLVM
define i128 @test_shrink_add_1(i128 %a, i128 %b) {
%small_a = trunc i128 %a to i64
%small_b = trunc i128 %b to i64
%big_a = zext i64 %small_a to i128
%big_b = zext i64 %small_b to i128
%r = add i128 %big_a, %big_b
ret i128 %r
}
define i128 @test_shrink_add_2(i128 %a, i128 %b) {
%small_a = trunc i128 %a to i64
%small_b = trunc i128 %b to i64
%big_a = zext i64 %small_a to i128
%big_b = zext i64 %small_b to i128
%r = add i128 %big_a, %big_b
%small_r = trunc i128 %r to i64
%big_r = zext i64 %small_r to i128
ret i128 %big_r
}
define i128 @test_shrink_mul_1(i128 %a, i128 %b) {
%small_a = trunc i128 %a to i64
%small_b = trunc i128 %b to i64
%big_a = zext i64 %small_a to i128
%big_b = zext i64 %small_b to i128
%r = mul i128 %big_a, %big_b
ret i128 %r
}
define i128 @test_shrink_mul_2(i128 %a, i128 %b) {
%small_a = trunc i128 %a to i64
%small_b = trunc i128 %b to i64
%big_a = zext i64 %small_a to i128
%big_b = zext i64 %small_b to i128
%r = mul i128 %big_a, %big_b
%small_r = trunc i128 %r to i64
%big_r = zext i64 %small_r to i128
ret i128 %big_r
}
; opt shrink.ll -S -O3 > shrink.opt.ll
; Function Attrs: norecurse nounwind readnone
define i128 @test_shrink_add_1(i128 %a, i128 %b) #0 {
%big_a = and i128 %a, 18446744073709551615
%big_b = and i128 %b, 18446744073709551615
%r = add nuw nsw i128 %big_b, %big_a
ret i128 %r
}
; Function Attrs: norecurse nounwind readnone
define i128 @test_shrink_add_2(i128 %a, i128 %b) #0 {
%r = add i128 %b, %a
%big_r = and i128 %r, 18446744073709551615
ret i128 %big_r
}
; Function Attrs: norecurse nounwind readnone
define i128 @test_shrink_mul_1(i128 %a, i128 %b) #0 {
%big_a = and i128 %a, 18446744073709551615
%big_b = and i128 %b, 18446744073709551615
%r = mul nuw i128 %big_b, %big_a
ret i128 %r
}
; Function Attrs: norecurse nounwind readnone
define i128 @test_shrink_mul_2(i128 %a, i128 %b) #0 {
%big_a = and i128 %a, 18446744073709551615
%big_b = and i128 %b, 18446744073709551615
%r = mul nuw i128 %big_b, %big_a
%big_r = and i128 %r, 18446744073709551615
ret i128 %big_r
}
attributes #0 = { norecurse nounwind readnone }
# llc -O3 shrink.opt.ll
.text
.file "shrink.opt.ll"
.globl test_shrink_add_1
.align 16, 0x90
.type test_shrink_add_1,@function
test_shrink_add_1: # @test_shrink_add_1
# BB#0:
addq %rdx, %rdi
sbbq %rdx, %rdx
andl $1, %edx
movq %rdi, %rax
retq
.Lfunc_end0:
.size test_shrink_add_1, .Lfunc_end0-test_shrink_add_1
.globl test_shrink_add_2
.align 16, 0x90
.type test_shrink_add_2,@function
test_shrink_add_2: # @test_shrink_add_2
# BB#0:
leaq (%rdi,%rdx), %rax
xorl %edx, %edx
retq
.Lfunc_end1:
.size test_shrink_add_2, .Lfunc_end1-test_shrink_add_2
.globl test_shrink_mul_1
.align 16, 0x90
.type test_shrink_mul_1,@function
test_shrink_mul_1: # @test_shrink_mul_1
# BB#0:
movq %rdx, %rax
mulq %rdi
retq
.Lfunc_end2:
.size test_shrink_mul_1, .Lfunc_end2-test_shrink_mul_1
.globl test_shrink_mul_2
.align 16, 0x90
.type test_shrink_mul_2,@function
test_shrink_mul_2: # @test_shrink_mul_2
# BB#0:
imulq %rdx, %rdi
xorl %edx, %edx
movq %rdi, %rax
retq
.Lfunc_end3:
.size test_shrink_mul_2, .Lfunc_end3-test_shrink_mul_2
.section ".note.GNU-stack","",@progbits
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment