mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Recommit "[InstCombine] Negator: -(X << C) --> X * (-1 << C)"
This reverts commit ac70b37a00dc02bd8923e0a4602d26be4581c570 which reverted commit 8aeb2fe13a4100b4c2e78d6ef75119304100cb1f because codegen tests got broken and i needed time to investigate. This shows some regressions in tests, but they are all around GEP's, so i'm not really sure how important those are. https://rise4fun.com/Alive/1Gn
This commit is contained in:
parent
30c0f960b8
commit
c3ca06f18c
@ -324,10 +324,16 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
|
||||
}
|
||||
case Instruction::Shl: {
|
||||
// `shl` is negatible if the first operand is negatible.
|
||||
Value *NegOp0 = negate(I->getOperand(0), Depth + 1);
|
||||
if (!NegOp0) // Early return.
|
||||
if (Value *NegOp0 = negate(I->getOperand(0), Depth + 1))
|
||||
return Builder.CreateShl(NegOp0, I->getOperand(1), I->getName() + ".neg");
|
||||
// Otherwise, `shl %x, C` can be interpreted as `mul %x, 1<<C`.
|
||||
auto *Op1C = dyn_cast<Constant>(I->getOperand(1));
|
||||
if (!Op1C) // Early return.
|
||||
return nullptr;
|
||||
return Builder.CreateShl(NegOp0, I->getOperand(1), I->getName() + ".neg");
|
||||
return Builder.CreateMul(
|
||||
I->getOperand(0),
|
||||
ConstantExpr::getShl(Constant::getAllOnesValue(Op1C->getType()), Op1C),
|
||||
I->getName() + ".neg");
|
||||
}
|
||||
case Instruction::Or:
|
||||
if (!haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1), DL, &AC, I,
|
||||
|
@ -149,7 +149,7 @@ define amdgpu_kernel void @use_local_size_z_8_16_2(i64 addrspace(1)* %out) #0 !r
|
||||
|
||||
; CHECK-LABEL: @local_size_x_8_16_2_wrong_group_id(
|
||||
; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.y()
|
||||
; CHECK: %group.id_x_group.size.x = shl i32 %group.id, 3
|
||||
; CHECK: %group.id_x_group.size.x.neg = mul i32 %group.id, -8
|
||||
define amdgpu_kernel void @local_size_x_8_16_2_wrong_group_id(i64 addrspace(1)* %out) #0 !reqd_work_group_size !0 {
|
||||
%dispatch.ptr = tail call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr()
|
||||
%gep.group.size.x = getelementptr inbounds i8, i8 addrspace(4)* %dispatch.ptr, i64 4
|
||||
@ -172,8 +172,7 @@ define amdgpu_kernel void @local_size_x_8_16_2_wrong_group_id(i64 addrspace(1)*
|
||||
; CHECK-LABEL: @local_size_x_8_16_2_wrong_grid_size(
|
||||
; CHECK: %grid.size.x = load i32, i32 addrspace(4)* %gep.grid.size.x.bc, align 4
|
||||
; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()
|
||||
; CHECK: %group.id_x_group.size.x = shl i32 %group.id, 3
|
||||
; CHECK: %sub = sub i32 %grid.size.x, %group.id_x_group.size.x
|
||||
; CHECK: %group.id_x_group.size.x.neg = mul i32 %group.id, -8
|
||||
define amdgpu_kernel void @local_size_x_8_16_2_wrong_grid_size(i64 addrspace(1)* %out) #0 !reqd_work_group_size !0 {
|
||||
%dispatch.ptr = tail call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr()
|
||||
%gep.group.size.x = getelementptr inbounds i8, i8 addrspace(4)* %dispatch.ptr, i64 4
|
||||
@ -196,8 +195,8 @@ define amdgpu_kernel void @local_size_x_8_16_2_wrong_group_id(i64 addrspace(1)*
|
||||
; CHECK-LABEL: @local_size_x_8_16_2_wrong_cmp_type(
|
||||
; CHECK: %grid.size.x = load i32, i32 addrspace(4)* %gep.grid.size.x.bc, align 4
|
||||
; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()
|
||||
; CHECK: %group.id_x_group.size.x = shl i32 %group.id, 3
|
||||
; CHECK: %sub = sub i32 %grid.size.x, %group.id_x_group.size.x
|
||||
; CHECK: %group.id_x_group.size.x.neg = mul i32 %group.id, -8
|
||||
; CHECK: %sub = add i32 %group.id_x_group.size.x.neg, %grid.size.x
|
||||
; CHECK: %cmp = icmp slt i32 %sub, 8
|
||||
; CHECK: %select = select i1 %cmp, i32 %sub, i32 8
|
||||
define amdgpu_kernel void @local_size_x_8_16_2_wrong_cmp_type(i64 addrspace(1)* %out) #0 !reqd_work_group_size !0 {
|
||||
@ -220,8 +219,8 @@ define amdgpu_kernel void @local_size_x_8_16_2_wrong_cmp_type(i64 addrspace(1)*
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @local_size_x_8_16_2_wrong_select(
|
||||
; CHECK: %group.id_x_group.size.x = shl i32 %group.id, 3
|
||||
; CHECK: %sub = sub i32 %grid.size.x, %group.id_x_group.size.x
|
||||
; CHECK: %group.id_x_group.size.x.neg = mul i32 %group.id, -8
|
||||
; CHECK: %sub = add i32 %group.id_x_group.size.x.neg, %grid.size.x
|
||||
; CHECK: %1 = icmp ugt i32 %sub, 8
|
||||
; CHECK: %select = select i1 %1, i32 %sub, i32 8
|
||||
; CHECK: %zext = zext i32 %select to i64
|
||||
@ -248,8 +247,8 @@ define amdgpu_kernel void @local_size_x_8_16_2_wrong_select(i64 addrspace(1)* %o
|
||||
; CHECK: %grid.size.x = load i16, i16 addrspace(4)* %gep.grid.size.x.bc, align 4
|
||||
; CHECK: %grid.size.x.zext = zext i16 %grid.size.x to i32
|
||||
; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()
|
||||
; CHECK: %group.id_x_group.size.x = shl i32 %group.id, 3
|
||||
; CHECK: %sub = sub i32 %grid.size.x.zext, %group.id_x_group.size.x
|
||||
; CHECK: %group.id_x_group.size.x.neg = mul i32 %group.id, -8
|
||||
; CHECK: %sub = add i32 %group.id_x_group.size.x.neg, %grid.size.x.zext
|
||||
define amdgpu_kernel void @use_local_size_x_8_16_2_wrong_grid_load_size(i64 addrspace(1)* %out) #0 !reqd_work_group_size !0 {
|
||||
%dispatch.ptr = tail call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr()
|
||||
%gep.group.size.x = getelementptr inbounds i8, i8 addrspace(4)* %dispatch.ptr, i64 4
|
||||
|
@ -512,7 +512,8 @@ define i1 @test24(i64 %i) {
|
||||
; unsigned overflow does not happen during offset computation
|
||||
define i1 @test24_neg_offs(i32* %p, i64 %offs) {
|
||||
; CHECK-LABEL: @test24_neg_offs(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OFFS:%.*]], -2
|
||||
; CHECK-NEXT: [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%p1 = getelementptr inbounds i32, i32* %p, i64 %offs
|
||||
|
@ -58,9 +58,8 @@ define i32 @test_inbounds_nuw_trunc([0 x i32]* %base, i64 %idx) {
|
||||
|
||||
define i64 @test_inbounds_nuw_swapped([0 x i32]* %base, i64 %idx) {
|
||||
; CHECK-LABEL: @test_inbounds_nuw_swapped(
|
||||
; CHECK-NEXT: [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 2
|
||||
; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, [[P2_IDX]]
|
||||
; CHECK-NEXT: ret i64 [[DIFF_NEG]]
|
||||
; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
|
||||
; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]
|
||||
;
|
||||
%p1 = getelementptr inbounds [0 x i32], [0 x i32]* %base, i64 0, i64 0
|
||||
%p2 = getelementptr inbounds [0 x i32], [0 x i32]* %base, i64 0, i64 %idx
|
||||
@ -73,8 +72,9 @@ define i64 @test_inbounds_nuw_swapped([0 x i32]* %base, i64 %idx) {
|
||||
; The sub and shl here could be nuw, but this is harder to handle.
|
||||
define i64 @test_inbounds_nuw_two_gep([0 x i32]* %base, i64 %idx, i64 %idx2) {
|
||||
; CHECK-LABEL: @test_inbounds_nuw_two_gep(
|
||||
; CHECK-NEXT: [[P1_IDX1_NEG:%.*]] = sub i64 [[IDX2:%.*]], [[IDX:%.*]]
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = shl i64 [[P1_IDX1_NEG]], 2
|
||||
; CHECK-NEXT: [[P1_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
|
||||
; CHECK-NEXT: [[P2_IDX_NEG_NEG:%.*]] = shl i64 [[IDX2:%.*]], 2
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = add i64 [[P2_IDX_NEG_NEG]], [[P1_IDX_NEG]]
|
||||
; CHECK-NEXT: ret i64 [[DOTNEG]]
|
||||
;
|
||||
%p1 = getelementptr inbounds [0 x i32], [0 x i32]* %base, i64 0, i64 %idx
|
||||
|
@ -1076,8 +1076,8 @@ define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) {
|
||||
; CHECK-LABEL: @negate_left_shift_by_constant(
|
||||
; CHECK-NEXT: [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]]
|
||||
; CHECK-NEXT: call void @use8(i8 [[T0]])
|
||||
; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], 4
|
||||
; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
|
||||
; CHECK-NEXT: [[T1_NEG:%.*]] = mul i8 [[T0]], -16
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret i8 [[T2]]
|
||||
;
|
||||
%t0 = sub i8 %k, %z
|
||||
|
@ -506,8 +506,8 @@ define i64 @test24b(i8* %P, i64 %A){
|
||||
|
||||
define i64 @test25(i8* %P, i64 %A){
|
||||
; CHECK-LABEL: @test25(
|
||||
; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = add i64 [[B_IDX]], -84
|
||||
; CHECK-NEXT: [[B_IDX_NEG_NEG:%.*]] = shl i64 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = add i64 [[B_IDX_NEG_NEG]], -84
|
||||
; CHECK-NEXT: ret i64 [[DOTNEG]]
|
||||
;
|
||||
%B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A
|
||||
@ -521,8 +521,8 @@ define i64 @test25(i8* %P, i64 %A){
|
||||
define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) {
|
||||
; CHECK-LABEL: @test25_as1(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i16
|
||||
; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i16 [[TMP1]], 1
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = add i16 [[B_IDX]], -84
|
||||
; CHECK-NEXT: [[B_IDX_NEG_NEG:%.*]] = shl i16 [[TMP1]], 1
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = add i16 [[B_IDX_NEG_NEG]], -84
|
||||
; CHECK-NEXT: ret i16 [[DOTNEG]]
|
||||
;
|
||||
%B = getelementptr inbounds [42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 0, i64 %A
|
||||
@ -557,9 +557,8 @@ define i64 @test_neg_shl_sub_extra_use1(i64 %a, i64 %b, i64* %p) {
|
||||
; CHECK-LABEL: @test_neg_shl_sub_extra_use1(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: store i64 [[SUB]], i64* [[P:%.*]], align 8
|
||||
; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[SUB]], 2
|
||||
; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[MUL]]
|
||||
; CHECK-NEXT: ret i64 [[NEG]]
|
||||
; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i64 [[SUB]], -4
|
||||
; CHECK-NEXT: ret i64 [[MUL_NEG]]
|
||||
;
|
||||
%sub = sub i64 %a, %b
|
||||
store i64 %sub, i64* %p
|
||||
@ -840,9 +839,10 @@ define i64 @test29(i8* %foo, i64 %i, i64 %j) {
|
||||
|
||||
define i64 @test30(i8* %foo, i64 %i, i64 %j) {
|
||||
; CHECK-LABEL: @test30(
|
||||
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = sub i64 [[GEP1_IDX]], [[J:%.*]]
|
||||
; CHECK-NEXT: ret i64 [[DOTNEG]]
|
||||
; CHECK-NEXT: [[GEP1_IDX_NEG:%.*]] = mul i64 [[I:%.*]], -4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_IDX_NEG]], [[J:%.*]]
|
||||
; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, [[TMP1]]
|
||||
; CHECK-NEXT: ret i64 [[DIFF_NEG]]
|
||||
;
|
||||
%bit = bitcast i8* %foo to i32*
|
||||
%gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
|
||||
@ -855,9 +855,10 @@ define i64 @test30(i8* %foo, i64 %i, i64 %j) {
|
||||
|
||||
define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
|
||||
; CHECK-LABEL: @test30_as1(
|
||||
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = sub i16 [[GEP1_IDX]], [[J:%.*]]
|
||||
; CHECK-NEXT: ret i16 [[DOTNEG]]
|
||||
; CHECK-NEXT: [[GEP1_IDX_NEG:%.*]] = mul i16 [[I:%.*]], -4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[GEP1_IDX_NEG]], [[J:%.*]]
|
||||
; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i16 0, [[TMP1]]
|
||||
; CHECK-NEXT: ret i16 [[DIFF_NEG]]
|
||||
;
|
||||
%bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
|
||||
%gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
|
||||
@ -1310,8 +1311,8 @@ define i64 @test61([100 x [100 x i8]]* %foo, i64 %i, i64 %j) {
|
||||
|
||||
define i32 @test62(i32 %A) {
|
||||
; CHECK-LABEL: @test62(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[C:%.*]] = sub i32 2, [[B]]
|
||||
; CHECK-NEXT: [[B_NEG:%.*]] = mul i32 [[A:%.*]], -2
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 [[B_NEG]], 2
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%B = sub i32 1, %A
|
||||
@ -1321,8 +1322,8 @@ define i32 @test62(i32 %A) {
|
||||
|
||||
define <2 x i32> @test62vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test62vec(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> <i32 2, i32 2>, [[B]]
|
||||
; CHECK-NEXT: [[B_NEG:%.*]] = mul <2 x i32> [[A:%.*]], <i32 -2, i32 -2>
|
||||
; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B_NEG]], <i32 2, i32 2>
|
||||
; CHECK-NEXT: ret <2 x i32> [[C]]
|
||||
;
|
||||
%B = sub <2 x i32> <i32 1, i32 1>, %A
|
||||
@ -1332,8 +1333,8 @@ define <2 x i32> @test62vec(<2 x i32> %A) {
|
||||
|
||||
define i32 @test63(i32 %A) {
|
||||
; CHECK-LABEL: @test63(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: ret i32 [[B]]
|
||||
; CHECK-NEXT: [[B_NEG_NEG:%.*]] = shl i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: ret i32 [[B_NEG_NEG]]
|
||||
;
|
||||
%B = sub i32 1, %A
|
||||
%C = shl i32 %B, 1
|
||||
@ -1343,8 +1344,8 @@ define i32 @test63(i32 %A) {
|
||||
|
||||
define <2 x i32> @test63vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test63vec(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: ret <2 x i32> [[B]]
|
||||
; CHECK-NEXT: [[B_NEG_NEG:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: ret <2 x i32> [[B_NEG_NEG]]
|
||||
;
|
||||
%B = sub <2 x i32> <i32 1, i32 1>, %A
|
||||
%C = shl <2 x i32> %B, <i32 1, i32 1>
|
||||
|
Loading…
x
Reference in New Issue
Block a user