Skip to content

Conversation

arichardson
Copy link
Member

@arichardson arichardson commented Sep 20, 2025

This is an overly broad check, the transformation made here can be done
safely for pointers with index!=repr width. This fixes the codegen
regression introduced by #105735
and should be beneficial for AMDGPU code-generation once the datalayout
there no longer uses the overly strict ni: specifier.

Created using spr 1.3.8-beta.1
Created using spr 1.3.8-beta.1

[skip ci]
@llvmbot
Copy link
Member

llvmbot commented Sep 20, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Alexander Richardson (arichardson)

Changes

This is an overly broad check, the transformation made here can be done
safely for pointers with index!=repr width. This fixes the codegen
regression introduced by #105735

We could probably relax this to allow it for everything except unstable
pointers but that can be done as a follow-up.


Full diff: https://github.com/llvm/llvm-project/pull/159890.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+11-7)
  • (modified) llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll (+10-8)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index a1f759dd1df83..792c242360751 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -525,28 +525,32 @@ static bool dominatesMergePoint(
 static ConstantInt *getConstantInt(Value *V, const DataLayout &DL) {
   // Normal constant int.
   ConstantInt *CI = dyn_cast<ConstantInt>(V);
-  if (CI || !isa<Constant>(V) || !V->getType()->isPointerTy() ||
-      DL.isNonIntegralPointerType(V->getType()))
+  if (CI || !isa<Constant>(V) || !V->getType()->isPointerTy())
     return CI;
 
   // This is some kind of pointer constant. Turn it into a pointer-sized
   // ConstantInt if possible.
-  IntegerType *PtrTy = cast<IntegerType>(DL.getIntPtrType(V->getType()));
+  IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(V->getType()));
 
   // Null pointer means 0, see SelectionDAGBuilder::getValue(const Value*).
   if (isa<ConstantPointerNull>(V))
-    return ConstantInt::get(PtrTy, 0);
+    return ConstantInt::get(IntPtrTy, 0);
 
-  // IntToPtr const int.
+  // IntToPtr const int, we can look through this unless the semantics of
+  // inttoptr for this address space aren't a simple bitcast.
+  // TODO: should this be relaxed to hasUnstableRepresentation? The
+  // transformation made here should also be safe for CHERI.
+  if (DL.shouldAvoidIntToPtr(V->getType()))
+    return nullptr;
   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
     if (CE->getOpcode() == Instruction::IntToPtr)
       if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(0))) {
         // The constant is very likely to have the right type already.
-        if (CI->getType() == PtrTy)
+        if (CI->getType() == IntPtrTy)
           return CI;
         else
           return cast<ConstantInt>(
-              ConstantFoldIntegerCast(CI, PtrTy, /*isSigned=*/false, DL));
+              ConstantFoldIntegerCast(CI, IntPtrTy, /*isSigned=*/false, DL));
       }
   return nullptr;
 }
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
index ddf64591776dd..0f50e0a95e8c1 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll
@@ -37,10 +37,11 @@ F:              ; preds = %0
 ; FIXME: Should be using a switch here
 define void @test1_ptr(ptr %V) {
 ; CHECK-LABEL: @test1_ptr(
-; CHECK-NEXT:    [[C1:%.*]] = icmp eq ptr [[V:%.*]], inttoptr (i32 4 to ptr)
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq ptr [[V]], inttoptr (i32 17 to ptr)
-; CHECK-NEXT:    [[CN:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    br i1 [[CN]], label [[T:%.*]], label [[F:%.*]]
+; CHECK-NEXT:    [[MAGICPTR:%.*]] = ptrtoint ptr [[V:%.*]] to i40
+; CHECK-NEXT:    switch i40 [[MAGICPTR]], label [[F:%.*]] [
+; CHECK-NEXT:      i40 17, label [[T:%.*]]
+; CHECK-NEXT:      i40 4, label [[T]]
+; CHECK-NEXT:    ]
 ; CHECK:       common.ret:
 ; CHECK-NEXT:    ret void
 ; CHECK:       T:
@@ -64,10 +65,11 @@ F:              ; preds = %0
 
 define void @test1_ptr_as1(ptr addrspace(1) %V) {
 ; CHECK-LABEL: @test1_ptr_as1(
-; CHECK-NEXT:    [[C1:%.*]] = icmp eq ptr addrspace(1) [[V:%.*]], inttoptr (i32 4 to ptr addrspace(1))
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq ptr addrspace(1) [[V]], inttoptr (i32 17 to ptr addrspace(1))
-; CHECK-NEXT:    [[CN:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    br i1 [[CN]], label [[T:%.*]], label [[F:%.*]]
+; CHECK-NEXT:    [[MAGICPTR:%.*]] = ptrtoint ptr addrspace(1) [[V:%.*]] to i40
+; CHECK-NEXT:    switch i40 [[MAGICPTR]], label [[F:%.*]] [
+; CHECK-NEXT:      i40 17, label [[T:%.*]]
+; CHECK-NEXT:      i40 4, label [[T]]
+; CHECK-NEXT:    ]
 ; CHECK:       common.ret:
 ; CHECK-NEXT:    ret void
 ; CHECK:       T:

@arichardson arichardson added the cheri Related to CHERI support label Sep 20, 2025
Created using spr 1.3.8-beta.1
Created using spr 1.3.8-beta.1
Created using spr 1.3.7-beta.1

[skip ci]
Created using spr 1.3.7-beta.1
Created using spr 1.3.8-beta.1
Created using spr 1.3.8-beta.1

[skip ci]
Created using spr 1.3.8-beta.1
Created using spr 1.3.8-beta.1

[skip ci]
Created using spr 1.3.8-beta.1
Created using spr 1.3.8-beta.1

[skip ci]
Created using spr 1.3.8-beta.1
@arichardson arichardson changed the base branch from users/arichardson/spr/main.simplifycfg-avoid-using-isnonintegralpointertype to main September 23, 2025 18:23
@arichardson arichardson merged commit d03bfc6 into main Sep 23, 2025
10 of 15 checks passed
@arichardson arichardson deleted the users/arichardson/spr/simplifycfg-avoid-using-isnonintegralpointertype branch September 23, 2025 18:23
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Sep 23, 2025
This is an overly broad check, the transformation made here can be done
safely for pointers with index!=repr width. This fixes the codegen
regression introduced by llvm/llvm-project#105735
and should be beneficial for AMDGPU code-generation once the datalayout
there no longer uses the overly strict `ni:` specifier.

Reviewed By: arsenm

Pull Request: llvm/llvm-project#159890
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cheri Related to CHERI support llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants