Skip to content

Commit 17baedd

Browse files
committed
[InstCombine] Relax the same-underlying-object constraint for the GEP canonicalization
1 parent 2f40705 commit 17baedd

File tree

2 files changed

+12
-19
lines changed

2 files changed

+12
-19
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,13 +2471,18 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
24712471

24722472
if (TyAllocSize == 1) {
24732473
// Canonicalize (gep i8* X, (ptrtoint Y)-(ptrtoint X)) to (bitcast Y),
2474-
// but only if both point to the same underlying object (otherwise
2475-
// provenance is not necessarily retained).
2474+
// but only if the result pointer is only used as if it were an integer,
2475+
// or both point to the same underlying object (otherwise provenance is
2476+
// not necessarily retained).
24762477
Value *X = GEP.getPointerOperand();
24772478
Value *Y;
24782479
if (match(GEP.getOperand(1),
24792480
m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X)))) &&
2480-
getUnderlyingObject(X) == getUnderlyingObject(Y))
2481+
(all_of(GEP.users(),
2482+
[](User *U) {
2483+
return isa<ICmpInst>(U) || isa<PtrToIntInst>(U);
2484+
}) ||
2485+
getUnderlyingObject(X) == getUnderlyingObject(Y)))
24812486
return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
24822487
} else {
24832488
// Canonicalize (gep T* X, V / sizeof(T)) to (gep i8* X, V)

llvm/test/Transforms/InstCombine/getelementptr.ll

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,11 +1539,7 @@ define ptr @gep_ashr_without_exact(ptr %p, i64 %off) {
15391539

15401540
define i1 @test_only_used_by_icmp(ptr %a, ptr %b, ptr %c) {
15411541
; CHECK-LABEL: @test_only_used_by_icmp(
1542-
; CHECK-NEXT: [[PA:%.*]] = ptrtoint ptr [[A:%.*]] to i64
1543-
; CHECK-NEXT: [[PB:%.*]] = ptrtoint ptr [[B:%.*]] to i64
1544-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[PB]], [[PA]]
1545-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[SUB]]
1546-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP]], [[C:%.*]]
1542+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]
15471543
; CHECK-NEXT: ret i1 [[CMP]]
15481544
;
15491545
%pa = ptrtoint ptr %a to i64
@@ -1556,11 +1552,7 @@ define i1 @test_only_used_by_icmp(ptr %a, ptr %b, ptr %c) {
15561552

15571553
define i64 @test_only_used_by_ptrtoint(ptr %a, ptr %b) {
15581554
; CHECK-LABEL: @test_only_used_by_ptrtoint(
1559-
; CHECK-NEXT: [[PA:%.*]] = ptrtoint ptr [[A:%.*]] to i64
1560-
; CHECK-NEXT: [[PB:%.*]] = ptrtoint ptr [[B:%.*]] to i64
1561-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[PB]], [[PA]]
1562-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[SUB]]
1563-
; CHECK-NEXT: [[VAL:%.*]] = ptrtoint ptr [[GEP]] to i64
1555+
; CHECK-NEXT: [[VAL:%.*]] = ptrtoint ptr [[B:%.*]] to i64
15641556
; CHECK-NEXT: ret i64 [[VAL]]
15651557
;
15661558
%pa = ptrtoint ptr %a to i64
@@ -1573,14 +1565,10 @@ define i64 @test_only_used_by_ptrtoint(ptr %a, ptr %b) {
15731565

15741566
define i64 @test_used_by_both(ptr %a, ptr %b, ptr %c) {
15751567
; CHECK-LABEL: @test_used_by_both(
1576-
; CHECK-NEXT: [[PA:%.*]] = ptrtoint ptr [[A:%.*]] to i64
1577-
; CHECK-NEXT: [[PB:%.*]] = ptrtoint ptr [[B:%.*]] to i64
1578-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[PB]], [[PA]]
1579-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[SUB]]
1580-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP]], [[C:%.*]]
1568+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]
15811569
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
15821570
; CHECK: if.then:
1583-
; CHECK-NEXT: [[VAL:%.*]] = ptrtoint ptr [[GEP]] to i64
1571+
; CHECK-NEXT: [[VAL:%.*]] = ptrtoint ptr [[B]] to i64
15841572
; CHECK-NEXT: ret i64 [[VAL]]
15851573
; CHECK: if.else:
15861574
; CHECK-NEXT: ret i64 0

0 commit comments

Comments
 (0)