Mercurial > hg > CbC > CbC_llvm
view test/Transforms/InstCombine/unsigned_saturated_sub.ll @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 3a76565eade5 |
children |
line wrap: on
line source
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -instcombine -S < %s | FileCheck %s ; Canonicalization of unsigned saturated subtraction idioms to ; usub.sat() intrinsics is tested here. declare void @use(i64) ; (a > b) ? a - b : 0 -> usub.sat(a, b) define i64 @max_sub_ugt(i64 %a, i64 %b) { ; CHECK-LABEL: @max_sub_ugt( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: ret i64 [[TMP1]] ; %cmp = icmp ugt i64 %a, %b %sub = sub i64 %a, %b %sel = select i1 %cmp, i64 %sub ,i64 0 ret i64 %sel } ; (a >= b) ? a - b : 0 -> usub.sat(a, b) define i64 @max_sub_uge(i64 %a, i64 %b) { ; CHECK-LABEL: @max_sub_uge( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: ret i64 [[TMP1]] ; %cmp = icmp uge i64 %a, %b %sub = sub i64 %a, %b %sel = select i1 %cmp, i64 %sub ,i64 0 ret i64 %sel } ; Again, with vectors: ; (a > b) ? a - b : 0 -> usub.sat(a, b) define <4 x i32> @max_sub_ugt_vec(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: @max_sub_ugt_vec( ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) ; CHECK-NEXT: ret <4 x i32> [[TMP1]] ; %cmp = icmp ugt <4 x i32> %a, %b %sub = sub <4 x i32> %a, %b %sel = select <4 x i1> %cmp, <4 x i32> %sub, <4 x i32> zeroinitializer ret <4 x i32> %sel } ; Use extra ops to thwart icmp swapping canonicalization. ; (b < a) ? a - b : 0 -> usub.sat(a, b) define i64 @max_sub_ult(i64 %a, i64 %b) { ; CHECK-LABEL: @max_sub_ult( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[B]], [[A]] ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]]) ; CHECK-NEXT: ret i64 [[TMP1]] ; %cmp = icmp ult i64 %b, %a %sub = sub i64 %a, %b %sel = select i1 %cmp, i64 %sub ,i64 0 %extrasub = sub i64 %b, %a call void @use(i64 %extrasub) ret i64 %sel } ; (b > a) ? 0 : a - b -> usub.sat(a, b) define i64 @max_sub_ugt_sel_swapped(i64 %a, i64 %b) { ; CHECK-LABEL: @max_sub_ugt_sel_swapped( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[B]], [[A]] ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]]) ; CHECK-NEXT: ret i64 [[TMP1]] ; %cmp = icmp ugt i64 %b, %a %sub = sub i64 %a, %b %sel = select i1 %cmp, i64 0 ,i64 %sub %extrasub = sub i64 %b, %a call void @use(i64 %extrasub) ret i64 %sel } ; (a < b) ? 0 : a - b -> usub.sat(a, b) define i64 @max_sub_ult_sel_swapped(i64 %a, i64 %b) { ; CHECK-LABEL: @max_sub_ult_sel_swapped( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: ret i64 [[TMP1]] ; %cmp = icmp ult i64 %a, %b %sub = sub i64 %a, %b %sel = select i1 %cmp, i64 0 ,i64 %sub ret i64 %sel } ; ((a > b) ? b - a : 0) -> -usub.sat(a, b) define i64 @neg_max_sub_ugt(i64 %a, i64 %b) { ; CHECK-LABEL: @neg_max_sub_ugt( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[TMP1]] ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[A]], [[B]] ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]]) ; CHECK-NEXT: ret i64 [[TMP2]] ; %cmp = icmp ugt i64 %a, %b %sub = sub i64 %b, %a %sel = select i1 %cmp, i64 %sub ,i64 0 %extrasub = sub i64 %a, %b call void @use(i64 %extrasub) ret i64 %sel } ; ((b < a) ? b - a : 0) -> -usub.sat(a, b) define i64 @neg_max_sub_ult(i64 %a, i64 %b) { ; CHECK-LABEL: @neg_max_sub_ult( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[TMP1]] ; CHECK-NEXT: ret i64 [[TMP2]] ; %cmp = icmp ult i64 %b, %a %sub = sub i64 %b, %a %sel = select i1 %cmp, i64 %sub ,i64 0 ret i64 %sel } ; ((b > a) ? 0 : b - a) -> -usub.sat(a, b) define i64 @neg_max_sub_ugt_sel_swapped(i64 %a, i64 %b) { ; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[TMP1]] ; CHECK-NEXT: ret i64 [[TMP2]] ; %cmp = icmp ugt i64 %b, %a %sub = sub i64 %b, %a %sel = select i1 %cmp, i64 0 ,i64 %sub ret i64 %sel } ; ((a < b) ? 0 : b - a) -> -usub.sat(a, b) define i64 @neg_max_sub_ult_sel_swapped(i64 %a, i64 %b) { ; CHECK-LABEL: @neg_max_sub_ult_sel_swapped( ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[TMP1]] ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[A]], [[B]] ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]]) ; CHECK-NEXT: ret i64 [[TMP2]] ; %cmp = icmp ult i64 %a, %b %sub = sub i64 %b, %a %sel = select i1 %cmp, i64 0 ,i64 %sub %extrasub = sub i64 %a, %b call void @use(i64 %extrasub) ret i64 %sel }