forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ConstantHoisting] Add a TTI hook to prevent hoisting. (llvm#69004)
Code generation can sometimes simplify expensive operations when an operand is constant. An example of this is divides on AArch64 where they can be rewritten using a cheaper sequence of multiplies and subtracts. Doing this is often better than hoisting expensive constants which are likely to be hoisted by MachineLICM anyway.
- Loading branch information
1 parent
8d7c979
commit 930b5b5
Showing
6 changed files
with
163 additions
and
10 deletions.
There are no files selected for viewing
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
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
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
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
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
125 changes: 116 additions & 9 deletions
125
llvm/test/Transforms/ConstantHoisting/AArch64/large-immediate.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 |
---|---|---|
@@ -1,27 +1,134 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 | ||
; RUN: opt -mtriple=arm64-darwin-unknown -S -passes=consthoist < %s | FileCheck %s | ||
|
||
define i128 @test1(i128 %a) nounwind { | ||
; CHECK-LABEL: test1 | ||
; CHECK: %const = bitcast i128 12297829382473034410122878 to i128 | ||
define i128 @test1(i128 %a) { | ||
; CHECK-LABEL: define i128 @test1( | ||
; CHECK-SAME: i128 [[A:%.*]]) { | ||
; CHECK-NEXT: [[CONST:%.*]] = bitcast i128 12297829382473034410122878 to i128 | ||
; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[A]], [[CONST]] | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i128 [[TMP1]], [[CONST]] | ||
; CHECK-NEXT: ret i128 [[TMP2]] | ||
; | ||
%1 = add i128 %a, 12297829382473034410122878 | ||
%2 = add i128 %1, 12297829382473034410122878 | ||
ret i128 %2 | ||
} | ||
|
||
; Check that we don't hoist large, but cheap constants | ||
define i512 @test2(i512 %a) nounwind { | ||
; CHECK-LABEL: test2 | ||
; CHECK-NOT: %const = bitcast i512 7 to i512 | ||
define i512 @test2(i512 %a) { | ||
; CHECK-LABEL: define i512 @test2( | ||
; CHECK-SAME: i512 [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = and i512 [[A]], 7 | ||
; CHECK-NEXT: [[TMP2:%.*]] = or i512 [[TMP1]], 7 | ||
; CHECK-NEXT: ret i512 [[TMP2]] | ||
; | ||
%1 = and i512 %a, 7 | ||
%2 = or i512 %1, 7 | ||
ret i512 %2 | ||
} | ||
|
||
; Check that we don't hoist the shift value of a shift instruction. | ||
define i512 @test3(i512 %a) nounwind { | ||
; CHECK-LABEL: test3 | ||
; CHECK-NOT: %const = bitcast i512 504 to i512 | ||
define i512 @test3(i512 %a) { | ||
; CHECK-LABEL: define i512 @test3( | ||
; CHECK-SAME: i512 [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = shl i512 [[A]], 504 | ||
; CHECK-NEXT: [[TMP2:%.*]] = ashr i512 [[TMP1]], 504 | ||
; CHECK-NEXT: ret i512 [[TMP2]] | ||
; | ||
%1 = shl i512 %a, 504 | ||
%2 = ashr i512 %1, 504 | ||
ret i512 %2 | ||
} | ||
|
||
; Ensure the code generator has the information necessary to simply sdiv. | ||
define i64 @sdiv(i64 %a) { | ||
; CHECK-LABEL: define i64 @sdiv( | ||
; CHECK-SAME: i64 [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[A]], 4294967087 | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087 | ||
; CHECK-NEXT: ret i64 [[TMP2]] | ||
; | ||
%1 = sdiv i64 %a, 4294967087 | ||
%2 = add i64 %1, 4294967087 | ||
ret i64 %2 | ||
} | ||
|
||
; Ensure the code generator has the information necessary to simply srem. | ||
define i64 @srem(i64 %a) { | ||
; CHECK-LABEL: define i64 @srem( | ||
; CHECK-SAME: i64 [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = srem i64 [[A]], 4294967087 | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087 | ||
; CHECK-NEXT: ret i64 [[TMP2]] | ||
; | ||
%1 = srem i64 %a, 4294967087 | ||
%2 = add i64 %1, 4294967087 | ||
ret i64 %2 | ||
} | ||
|
||
; Ensure the code generator has the information necessary to simply udiv. | ||
define i64 @udiv(i64 %a) { | ||
; CHECK-LABEL: define i64 @udiv( | ||
; CHECK-SAME: i64 [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = udiv i64 [[A]], 4294967087 | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087 | ||
; CHECK-NEXT: ret i64 [[TMP2]] | ||
; | ||
%1 = udiv i64 %a, 4294967087 | ||
%2 = add i64 %1, 4294967087 | ||
ret i64 %2 | ||
} | ||
|
||
; Ensure the code generator has the information necessary to simply urem. | ||
define i64 @urem(i64 %a) { | ||
; CHECK-LABEL: define i64 @urem( | ||
; CHECK-SAME: i64 [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[A]], 4294967087 | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4294967087 | ||
; CHECK-NEXT: ret i64 [[TMP2]] | ||
; | ||
%1 = urem i64 %a, 4294967087 | ||
%2 = add i64 %1, 4294967087 | ||
ret i64 %2 | ||
} | ||
|
||
; Code generator will not decompose divide like operations when the divisor is | ||
; no a constant. | ||
define i64 @sdiv_non_const_divisor(i64 %a) { | ||
; CHECK-LABEL: define i64 @sdiv_non_const_divisor( | ||
; CHECK-SAME: i64 [[A:%.*]]) { | ||
; CHECK-NEXT: [[CONST:%.*]] = bitcast i64 4294967087 to i64 | ||
; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[CONST]], [[A]] | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]] | ||
; CHECK-NEXT: ret i64 [[TMP2]] | ||
; | ||
%1 = sdiv i64 4294967087, %a | ||
%2 = add i64 %1, 4294967087 | ||
ret i64 %2 | ||
} | ||
|
||
; Code generator emits divide instructions when optimising for size. | ||
define i64 @sdiv_minsize(i64 %a) minsize { | ||
; CHECK-LABEL: define i64 @sdiv_minsize( | ||
; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR0:[0-9]+]] { | ||
; CHECK-NEXT: [[CONST:%.*]] = bitcast i64 4294967087 to i64 | ||
; CHECK-NEXT: [[TMP1:%.*]] = sdiv i64 [[A]], [[CONST]] | ||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[CONST]] | ||
; CHECK-NEXT: ret i64 [[TMP2]] | ||
; | ||
%1 = sdiv i64 %a, 4294967087 | ||
%2 = add i64 %1, 4294967087 | ||
ret i64 %2 | ||
} | ||
|
||
define <2 x i64> @sdiv_v2i64(<2 x i64> %a) { | ||
; CHECK-LABEL: define <2 x i64> @sdiv_v2i64( | ||
; CHECK-SAME: <2 x i64> [[A:%.*]]) { | ||
; CHECK-NEXT: [[TMP1:%.*]] = sdiv <2 x i64> [[A]], <i64 4294967087, i64 4294967087> | ||
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP1]], <i64 4294967087, i64 4294967087> | ||
; CHECK-NEXT: ret <2 x i64> [[TMP2]] | ||
; | ||
%1 = sdiv <2 x i64> %a, <i64 4294967087, i64 4294967087> | ||
%2 = add <2 x i64> %1, <i64 4294967087, i64 4294967087> | ||
ret <2 x i64> %2 | ||
} |