| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s | |
| target datalayout = "p1:32:32" | |
| define i64 @bitextract_i64(b64 %x) { | |
| ; CHECK-LABEL: define i64 @bitextract_i64( | |
| ; CHECK-SAME: b64 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast b64 [[X]] to i64 | |
| ; CHECK-NEXT: ret i64 [[R]] | |
| ; | |
| %r = bitextract i64, b64 %x, i32 0 | |
| ret i64 %r | |
| } | |
| define double @bitextract_double(b64 %x) { | |
| ; CHECK-LABEL: define double @bitextract_double( | |
| ; CHECK-SAME: b64 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast b64 [[X]] to double | |
| ; CHECK-NEXT: ret double [[R]] | |
| ; | |
| %r = bitextract double, b64 %x, i32 0 | |
| ret double %r | |
| } | |
| define ptr @bitextract_ptr(b64 %x) { | |
| ; CHECK-LABEL: define ptr @bitextract_ptr( | |
| ; CHECK-SAME: b64 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast b64 [[X]] to ptr | |
| ; CHECK-NEXT: ret ptr [[R]] | |
| ; | |
| %r = bitextract ptr, b64 %x, i32 0 | |
| ret ptr %r | |
| } | |
| define ptr addrspace(1) @bitextract_ptr_as1(b32 %x) { | |
| ; CHECK-LABEL: define ptr addrspace(1) @bitextract_ptr_as1( | |
| ; CHECK-SAME: b32 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast b32 [[X]] to ptr addrspace(1) | |
| ; CHECK-NEXT: ret ptr addrspace(1) [[R]] | |
| ; | |
| %r = bitextract ptr addrspace(1), b32 %x, i32 0 | |
| ret ptr addrspace(1) %r | |
| } | |
| define b64 @bitinsert_i64(b64 %x, i64 %y) { | |
| ; CHECK-LABEL: define b64 @bitinsert_i64( | |
| ; CHECK-SAME: b64 [[X:%.*]], i64 [[Y:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast i64 [[Y]] to b64 | |
| ; CHECK-NEXT: ret b64 [[R]] | |
| ; | |
| %r = bitinsert b64 %x, i64 %y, i32 0 | |
| ret b64 %r | |
| } | |
| define b32 @bitinsert_float(b32 %x, float %y) { | |
| ; CHECK-LABEL: define b32 @bitinsert_float( | |
| ; CHECK-SAME: b32 [[X:%.*]], float [[Y:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast float [[Y]] to b32 | |
| ; CHECK-NEXT: ret b32 [[R]] | |
| ; | |
| %r = bitinsert b32 %x, float %y, i32 0 | |
| ret b32 %r | |
| } | |
| define b64 @bitinsert_ptr(b64 %x, ptr %y) { | |
| ; CHECK-LABEL: define b64 @bitinsert_ptr( | |
| ; CHECK-SAME: b64 [[X:%.*]], ptr [[Y:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitcast ptr [[Y]] to b64 | |
| ; CHECK-NEXT: ret b64 [[R]] | |
| ; | |
| %r = bitinsert b64 %x, ptr %y, i32 0 | |
| ret b64 %r | |
| } | |
| define i8 @bitextract_bitinsert(b32 %x, i8 %y) { | |
| ; CHECK-LABEL: define i8 @bitextract_bitinsert( | |
| ; CHECK-SAME: b32 [[X:%.*]], i8 [[Y:%.*]]) { | |
| ; CHECK-NEXT: ret i8 [[Y]] | |
| ; | |
| %i = bitinsert b32 %x, i8 %y, i32 8 | |
| %r = bitextract i8, b32 %i, i32 8 | |
| ret i8 %r | |
| } | |
| ; The result is narrower than the source. | |
| define i32 @neg_bitextract_partial(b64 %x) { | |
| ; CHECK-LABEL: define i32 @neg_bitextract_partial( | |
| ; CHECK-SAME: b64 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitextract i32, b64 [[X]], i32 0 | |
| ; CHECK-NEXT: ret i32 [[R]] | |
| ; | |
| %r = bitextract i32, b64 %x, i32 0 | |
| ret i32 %r | |
| } | |
| ; The pointer is narrower than the source. | |
| define ptr @neg_bitextract_ptr_narrow(b128 %x) { | |
| ; CHECK-LABEL: define ptr @neg_bitextract_ptr_narrow( | |
| ; CHECK-SAME: b128 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitextract ptr, b128 [[X]], i32 0 | |
| ; CHECK-NEXT: ret ptr [[R]] | |
| ; | |
| %r = bitextract ptr, b128 %x, i32 0 | |
| ret ptr %r | |
| } | |
| ; Pointers in addrspace(1) are 32 bits wide. | |
| define ptr addrspace(1) @neg_bitextract_ptr_as1(b64 %x) { | |
| ; CHECK-LABEL: define ptr addrspace(1) @neg_bitextract_ptr_as1( | |
| ; CHECK-SAME: b64 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitextract ptr addrspace(1), b64 [[X]], i32 0 | |
| ; CHECK-NEXT: ret ptr addrspace(1) [[R]] | |
| ; | |
| %r = bitextract ptr addrspace(1), b64 %x, i32 0 | |
| ret ptr addrspace(1) %r | |
| } | |
| ; The offset may not be zero. | |
| define i64 @neg_bitextract_variable_offset(b64 %x, i32 %n) { | |
| ; CHECK-LABEL: define i64 @neg_bitextract_variable_offset( | |
| ; CHECK-SAME: b64 [[X:%.*]], i32 [[N:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitextract i64, b64 [[X]], i32 [[N]] | |
| ; CHECK-NEXT: ret i64 [[R]] | |
| ; | |
| %r = bitextract i64, b64 %x, i32 %n | |
| ret i64 %r | |
| } | |
| ; The value is narrower than the base. | |
| define b64 @neg_bitinsert_partial(b64 %x, i32 %y) { | |
| ; CHECK-LABEL: define b64 @neg_bitinsert_partial( | |
| ; CHECK-SAME: b64 [[X:%.*]], i32 [[Y:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitinsert b64 [[X]], i32 [[Y]], i32 0 | |
| ; CHECK-NEXT: ret b64 [[R]] | |
| ; | |
| %r = bitinsert b64 %x, i32 %y, i32 0 | |
| ret b64 %r | |
| } | |
| ; The offset may not be zero. | |
| define b64 @neg_bitinsert_variable_offset(b64 %x, i64 %y, i32 %n) { | |
| ; CHECK-LABEL: define b64 @neg_bitinsert_variable_offset( | |
| ; CHECK-SAME: b64 [[X:%.*]], i64 [[Y:%.*]], i32 [[N:%.*]]) { | |
| ; CHECK-NEXT: [[R:%.*]] = bitinsert b64 [[X]], i64 [[Y]], i32 [[N]] | |
| ; CHECK-NEXT: ret b64 [[R]] | |
| ; | |
| %r = bitinsert b64 %x, i64 %y, i32 %n | |
| ret b64 %r | |
| } |