| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=instcombine -S < %s | FileCheck %s |
| |
| ; Test folding of ~x | (x - 1) to ~(x & -x) |
| |
| define i64 @fold_or_not_dec(i64 %x) { |
| ; CHECK-LABEL: define i64 @fold_or_not_dec( |
| ; CHECK-SAME: i64 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[X]] |
| ; CHECK-NEXT: [[AND:%.*]] = and i64 [[X]], [[TMP1]] |
| ; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[AND]], -1 |
| ; CHECK-NEXT: ret i64 [[NOT]] |
| ; |
| %xor = xor i64 %x, -1 |
| %add = add i64 %x, -1 |
| %or = or i64 %xor, %add |
| ret i64 %or |
| } |
| |
| define i64 @fold_or_dec_not(i64 %x) { |
| ; CHECK-LABEL: define i64 @fold_or_dec_not( |
| ; CHECK-SAME: i64 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[X]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[X]], [[TMP1]] |
| ; CHECK-NEXT: [[OR:%.*]] = xor i64 [[TMP2]], -1 |
| ; CHECK-NEXT: ret i64 [[OR]] |
| ; |
| %xor = xor i64 %x, -1 |
| %add = add i64 %x, -1 |
| %or = or i64 %add, %xor |
| ret i64 %or |
| } |
| |
| |
| ; NEGATIVE TEST: add has multiple uses |
| define i64 @negative_multiuse_add(i64 %x, ptr %p) { |
| ; CHECK-LABEL: define i64 @negative_multiuse_add( |
| ; CHECK-SAME: i64 [[X:%.*]], ptr [[P:%.*]]) { |
| ; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X]], -1 |
| ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X]], -1 |
| ; CHECK-NEXT: store i64 [[ADD]], ptr [[P]], align 4 |
| ; CHECK-NEXT: [[OR:%.*]] = or i64 [[ADD]], [[XOR]] |
| ; CHECK-NEXT: ret i64 [[OR]] |
| ; |
| %xor = xor i64 %x, -1 |
| %add = add i64 %x, -1 |
| store i64 %add, ptr %p ; second use of %add |
| %or = or i64 %add, %xor |
| ret i64 %or |
| } |
| |
| ; NEGATIVE TEST: xor has multiple uses |
| define i64 @negative_multiuse_xor(i64 %x, ptr %p) { |
| ; CHECK-LABEL: define i64 @negative_multiuse_xor( |
| ; CHECK-SAME: i64 [[X:%.*]], ptr [[P:%.*]]) { |
| ; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X]], -1 |
| ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X]], -1 |
| ; CHECK-NEXT: store i64 [[XOR]], ptr [[P]], align 4 |
| ; CHECK-NEXT: [[OR:%.*]] = or i64 [[ADD]], [[XOR]] |
| ; CHECK-NEXT: ret i64 [[OR]] |
| ; |
| %xor = xor i64 %x, -1 |
| %add = add i64 %x, -1 |
| store i64 %xor, ptr %p ; second use of %xor |
| %or = or i64 %add, %xor |
| ret i64 %or |
| } |
| |