| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -instcombine-unsafe-select-transform=0 -instcombine -S | FileCheck %s |
| |
| ; TODO: All of these should be optimized to a single instruction of select/ |
| ; and/or. |
| |
| ; 1. --- X /\ (X /\ Y) --- |
| |
| define i1 @merge_logical_and_and(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_and_and( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %X, i1 %Y, i1 false |
| %res = and i1 %X, %c |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ands(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ands( |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = select i1 %X, i1 %Y, i1 false |
| %res = select i1 %X, i1 %c, i1 false |
| ret i1 %res |
| } |
| |
| define i1 @merge_and_logical_and(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_and_logical_and( |
| ; CHECK-NEXT: [[C:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X]], i1 [[C]], i1 false |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = and i1 %X, %Y |
| %res = select i1 %X, i1 %c, i1 false |
| ret i1 %res |
| } |
| |
| ; 2. --- X /\ (Y /\ X) --- |
| |
| ; This can be optimized to 'and i1 %X, %Y' |
| define i1 @merge_logical_and_and2(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_and_and2( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %Y, i1 %X, i1 false |
| %res = and i1 %X, %c |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ands2(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ands2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[TMP1]] |
| ; |
| %c = select i1 %Y, i1 %X, i1 false |
| %res = select i1 %X, i1 %c, i1 false |
| ret i1 %res |
| } |
| |
| define i1 @merge_and_logical_and2(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_and_logical_and2( |
| ; CHECK-NEXT: [[C:%.*]] = and i1 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X]], i1 [[C]], i1 false |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = and i1 %Y, %X |
| %res = select i1 %X, i1 %c, i1 false |
| ret i1 %res |
| } |
| |
| ; 3. --- (X /\ Y) /\ X --- |
| |
| define i1 @merge_logical_and_and3(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_and_and3( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %X, i1 %Y, i1 false |
| %res = and i1 %c, %X |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ands3(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ands3( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i1 [[X]], i1 false |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = select i1 %X, i1 %Y, i1 false |
| %res = select i1 %c, i1 %X, i1 false |
| ret i1 %res |
| } |
| |
| ; This can be optimized to 'and i1 %X, %Y' |
| define i1 @merge_and_logical_and3(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_and_logical_and3( |
| ; CHECK-NEXT: [[C:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = and i1 %X, %Y |
| %res = select i1 %c, i1 %X, i1 false |
| ret i1 %res |
| } |
| |
| ; 4. --- (Y /\ X) /\ X --- |
| |
| ; This can be optimized to 'and i1 %X, %Y' |
| define i1 @merge_logical_and_and4(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_and_and4( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %Y, i1 %X, i1 false |
| %res = and i1 %c, %X |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ands4(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ands4( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i1 [[X]], i1 false |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = select i1 %Y, i1 %X, i1 false |
| %res = select i1 %c, i1 %X, i1 false |
| ret i1 %res |
| } |
| |
| ; This can be optimized to 'and i1 %X, %Y' |
| define i1 @merge_and_logical_and4(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_and_logical_and4( |
| ; CHECK-NEXT: [[C:%.*]] = and i1 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = and i1 %Y, %X |
| %res = select i1 %c, i1 %X, i1 false |
| ret i1 %res |
| } |
| |
| |
| ; 5. --- X \/ (X \/ Y) --- |
| |
| define i1 @merge_logical_or_or(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_or_or( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %X, i1 true, i1 %Y |
| %res = or i1 %X, %c |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ors(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ors( |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = select i1 %X, i1 true, i1 %Y |
| %res = select i1 %X, i1 true, i1 %c |
| ret i1 %res |
| } |
| |
| define i1 @merge_or_logical_or(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_or_logical_or( |
| ; CHECK-NEXT: [[C:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X]], i1 true, i1 [[C]] |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = or i1 %X, %Y |
| %res = select i1 %X, i1 true, i1 %c |
| ret i1 %res |
| } |
| |
| ; 6. --- X \/ (Y \/ X) --- |
| |
| ; This can be optimized to 'or i1 %X, %Y' |
| define i1 @merge_logical_or_or2(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_or_or2( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %Y, i1 true, i1 %X |
| %res = or i1 %X, %c |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ors2(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ors2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[TMP1]] |
| ; |
| %c = select i1 %Y, i1 true, i1 %X |
| %res = select i1 %X, i1 true, i1 %c |
| ret i1 %res |
| } |
| |
| define i1 @merge_or_logical_or2(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_or_logical_or2( |
| ; CHECK-NEXT: [[C:%.*]] = or i1 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X]], i1 true, i1 [[C]] |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = or i1 %Y, %X |
| %res = select i1 %X, i1 true, i1 %c |
| ret i1 %res |
| } |
| |
| ; 7. --- (X \/ Y) \/ X --- |
| |
| define i1 @merge_logical_or_or3(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_or_or3( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %X, i1 true, i1 %Y |
| %res = or i1 %c, %X |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ors3(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ors3( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i1 true, i1 [[X]] |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = select i1 %X, i1 true, i1 %Y |
| %res = select i1 %c, i1 true, i1 %X |
| ret i1 %res |
| } |
| |
| ; This can be optimized to 'or i1 %Y, %X' |
| define i1 @merge_or_logical_or3(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_or_logical_or3( |
| ; CHECK-NEXT: [[C:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = or i1 %X, %Y |
| %res = select i1 %c, i1 true, i1 %X |
| ret i1 %res |
| } |
| |
| ; 8. --- (Y \/ X) \/ X --- |
| |
| ; This can be optimized to 'or i1 %Y, %X' |
| define i1 @merge_logical_or_or4(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_logical_or_or4( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = select i1 %Y, i1 true, i1 %X |
| %res = or i1 %c, %X |
| ret i1 %res |
| } |
| |
| define i1 @merge_two_logical_ors4(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_two_logical_ors4( |
| ; CHECK-NEXT: [[C:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X:%.*]] |
| ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i1 true, i1 [[X]] |
| ; CHECK-NEXT: ret i1 [[RES]] |
| ; |
| %c = select i1 %Y, i1 true, i1 %X |
| %res = select i1 %c, i1 true, i1 %X |
| ret i1 %res |
| } |
| |
| ; This can be optimized to 'or i1 %Y, %X' |
| define i1 @merge_or_logical_or4(i1 %X, i1 %Y) { |
| ; CHECK-LABEL: @merge_or_logical_or4( |
| ; CHECK-NEXT: [[C:%.*]] = or i1 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c = or i1 %Y, %X |
| %res = select i1 %c, i1 true, i1 %X |
| ret i1 %res |
| } |
| |