-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[InstCombine] Introduce tests for D153963
Introduce test cases for folding binops of `select` and cast of the `select` condition. Differential Revision: https://reviews.llvm.org/D155510
- Loading branch information
1 parent
057fc8e
commit c9fd7ac
Showing
1 changed file
with
240 additions
and
0 deletions.
There are no files selected for viewing
240 changes: 240 additions & 0 deletions
240
llvm/test/Transforms/InstCombine/binop-select-cast-of-select-cond.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 | ||
; RUN: opt < %s -passes=instcombine -S | FileCheck %s | ||
|
||
define i64 @add_select_zext(i1 %c) { | ||
; CHECK-LABEL: define i64 @add_select_zext | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 | ||
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[SEL]], [[EXT]] | ||
; CHECK-NEXT: ret i64 [[ADD]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%ext = zext i1 %c to i64 | ||
%add = add i64 %sel, %ext | ||
ret i64 %add | ||
} | ||
|
||
define i64 @add_select_sext(i1 %c) { | ||
; CHECK-LABEL: define i64 @add_select_sext | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 | ||
; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SEL]], [[EXT]] | ||
; CHECK-NEXT: ret i64 [[ADD]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%ext = sext i1 %c to i64 | ||
%add = add i64 %sel, %ext | ||
ret i64 %add | ||
} | ||
|
||
define i64 @add_select_not_zext(i1 %c) { | ||
; CHECK-LABEL: define i64 @add_select_not_zext | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 | ||
; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C]], true | ||
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[NOT_C]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[SEL]], [[EXT]] | ||
; CHECK-NEXT: ret i64 [[ADD]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%not.c = xor i1 %c, true | ||
%ext = zext i1 %not.c to i64 | ||
%add = add i64 %sel, %ext | ||
ret i64 %add | ||
} | ||
|
||
define i64 @add_select_not_sext(i1 %c) { | ||
; CHECK-LABEL: define i64 @add_select_not_sext | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 | ||
; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C]], true | ||
; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[NOT_C]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SEL]], [[EXT]] | ||
; CHECK-NEXT: ret i64 [[ADD]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%not.c = xor i1 %c, true | ||
%ext = sext i1 %not.c to i64 | ||
%add = add i64 %sel, %ext | ||
ret i64 %add | ||
} | ||
|
||
define i64 @sub_select_sext(i1 %c, i64 %arg) { | ||
; CHECK-LABEL: define i64 @sub_select_sext | ||
; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 [[ARG]] | ||
; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[SUB:%.*]] = add i64 [[SEL]], [[EXT_NEG]] | ||
; CHECK-NEXT: ret i64 [[SUB]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 %arg | ||
%ext = sext i1 %c to i64 | ||
%sub = sub i64 %sel, %ext | ||
ret i64 %sub | ||
} | ||
|
||
define i64 @sub_select_not_zext(i1 %c, i64 %arg) { | ||
; CHECK-LABEL: define i64 @sub_select_not_zext | ||
; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[ARG]], i64 64 | ||
; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C]], true | ||
; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[NOT_C]] to i64 | ||
; CHECK-NEXT: [[SUB:%.*]] = add i64 [[SEL]], [[EXT_NEG]] | ||
; CHECK-NEXT: ret i64 [[SUB]] | ||
; | ||
%sel = select i1 %c, i64 %arg, i64 64 | ||
%not.c = xor i1 %c, true | ||
%ext = zext i1 %not.c to i64 | ||
%sub = sub i64 %sel, %ext | ||
ret i64 %sub | ||
} | ||
|
||
define i64 @sub_select_not_sext(i1 %c, i64 %arg) { | ||
; CHECK-LABEL: define i64 @sub_select_not_sext | ||
; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[ARG]], i64 64 | ||
; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C]], true | ||
; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[NOT_C]] to i64 | ||
; CHECK-NEXT: [[SUB:%.*]] = add i64 [[SEL]], [[EXT_NEG]] | ||
; CHECK-NEXT: ret i64 [[SUB]] | ||
; | ||
%sel = select i1 %c, i64 %arg, i64 64 | ||
%not.c = xor i1 %c, true | ||
%ext = sext i1 %not.c to i64 | ||
%sub = sub i64 %sel, %ext | ||
ret i64 %sub | ||
} | ||
|
||
define i64 @mul_select_zext(i1 %c, i64 %arg) { | ||
; CHECK-LABEL: define i64 @mul_select_zext | ||
; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { | ||
; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C]], i64 [[ARG]], i64 0 | ||
; CHECK-NEXT: ret i64 [[MUL]] | ||
; | ||
%sel = select i1 %c, i64 %arg, i64 1 | ||
%ext = zext i1 %c to i64 | ||
%mul = mul i64 %sel, %ext | ||
ret i64 %mul | ||
} | ||
|
||
define i64 @mul_select_sext(i1 %c) { | ||
; CHECK-LABEL: define i64 @mul_select_sext | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C]], i64 6, i64 0 | ||
; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[EXT]], [[TMP1]] | ||
; CHECK-NEXT: ret i64 [[MUL]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%ext = sext i1 %c to i64 | ||
%mul = mul i64 %sel, %ext | ||
ret i64 %mul | ||
} | ||
|
||
define i64 @select_zext_different_condition(i1 %c, i1 %d) { | ||
; CHECK-LABEL: define i64 @select_zext_different_condition | ||
; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 | ||
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[D]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[SEL]], [[EXT]] | ||
; CHECK-NEXT: ret i64 [[ADD]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%ext = zext i1 %d to i64 | ||
%add = add i64 %sel, %ext | ||
ret i64 %add | ||
} | ||
|
||
define <2 x i64> @vector_test(i1 %c) { | ||
; CHECK-LABEL: define <2 x i64> @vector_test | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], <2 x i64> <i64 64, i64 64>, <2 x i64> <i64 1, i64 1> | ||
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[VEC0:%.*]] = insertelement <2 x i64> undef, i64 [[EXT]], i64 0 | ||
; CHECK-NEXT: [[VEC1:%.*]] = shufflevector <2 x i64> [[VEC0]], <2 x i64> poison, <2 x i32> zeroinitializer | ||
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw <2 x i64> [[SEL]], [[VEC1]] | ||
; CHECK-NEXT: ret <2 x i64> [[ADD]] | ||
; | ||
%sel = select i1 %c, <2 x i64> <i64 64, i64 64>, <2 x i64> <i64 1, i64 1> | ||
%ext = zext i1 %c to i64 | ||
%vec0 = insertelement <2 x i64> undef, i64 %ext, i32 0 | ||
%vec1 = insertelement <2 x i64> %vec0, i64 %ext, i32 1 | ||
%add = add <2 x i64> %sel, %vec1 | ||
ret <2 x i64> %add | ||
} | ||
|
||
define i64 @multiuse_add(i1 %c) { | ||
; CHECK-LABEL: define i64 @multiuse_add | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 | ||
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[SEL]], [[EXT]] | ||
; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i64 [[ADD]], 1 | ||
; CHECK-NEXT: ret i64 [[ADD2]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 1 | ||
%ext = zext i1 %c to i64 | ||
%add = add i64 %sel, %ext | ||
%add2 = add i64 %add, 1 | ||
ret i64 %add2 | ||
} | ||
|
||
define i64 @multiuse_select(i1 %c) { | ||
; CHECK-LABEL: define i64 @multiuse_select | ||
; CHECK-SAME: (i1 [[C:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 0 | ||
; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SEL]], [[EXT_NEG]] | ||
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i64 [[SEL]], [[ADD]] | ||
; CHECK-NEXT: ret i64 [[MUL]] | ||
; | ||
%sel = select i1 %c, i64 64, i64 0 | ||
%ext = zext i1 %c to i64 | ||
%add = sub i64 %sel, %ext | ||
%mul = mul i64 %sel, %add | ||
ret i64 %mul | ||
} | ||
|
||
define i64 @select_non_const_sides(i1 %c, i64 %arg1, i64 %arg2) { | ||
; CHECK-LABEL: define i64 @select_non_const_sides | ||
; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG1:%.*]], i64 [[ARG2:%.*]]) { | ||
; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[C]] to i64 | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[ARG1]], i64 [[ARG2]] | ||
; CHECK-NEXT: [[SUB:%.*]] = add i64 [[SEL]], [[EXT_NEG]] | ||
; CHECK-NEXT: ret i64 [[SUB]] | ||
; | ||
%ext = zext i1 %c to i64 | ||
%sel = select i1 %c, i64 %arg1, i64 %arg2 | ||
%sub = sub i64 %sel, %ext | ||
ret i64 %sub | ||
} | ||
|
||
define i6 @sub_select_sext_op_swapped_non_const_args(i1 %c, i6 %argT, i6 %argF) { | ||
; CHECK-LABEL: define i6 @sub_select_sext_op_swapped_non_const_args | ||
; CHECK-SAME: (i1 [[C:%.*]], i6 [[ARGT:%.*]], i6 [[ARGF:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i6 [[ARGT]], i6 [[ARGF]] | ||
; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[C]] to i6 | ||
; CHECK-NEXT: [[SUB:%.*]] = sub i6 [[EXT]], [[SEL]] | ||
; CHECK-NEXT: ret i6 [[SUB]] | ||
; | ||
%sel = select i1 %c, i6 %argT, i6 %argF | ||
%ext = sext i1 %c to i6 | ||
%sub = sub i6 %ext, %sel | ||
ret i6 %sub | ||
} | ||
|
||
define i6 @sub_select_zext_op_swapped_non_const_args(i1 %c, i6 %argT, i6 %argF) { | ||
; CHECK-LABEL: define i6 @sub_select_zext_op_swapped_non_const_args | ||
; CHECK-SAME: (i1 [[C:%.*]], i6 [[ARGT:%.*]], i6 [[ARGF:%.*]]) { | ||
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i6 [[ARGT]], i6 [[ARGF]] | ||
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[C]] to i6 | ||
; CHECK-NEXT: [[SUB:%.*]] = sub i6 [[EXT]], [[SEL]] | ||
; CHECK-NEXT: ret i6 [[SUB]] | ||
; | ||
%sel = select i1 %c, i6 %argT, i6 %argF | ||
%ext = zext i1 %c to i6 | ||
%sub = sub i6 %ext, %sel | ||
ret i6 %sub | ||
} |