diff --git a/clang/test/CodeGenOpenCL/overload.cl b/clang/test/CodeGenOpenCL/overload.cl --- a/clang/test/CodeGenOpenCL/overload.cl +++ b/clang/test/CodeGenOpenCL/overload.cl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -no-opaque-pointers -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s -// RUN: %clang_cc1 -no-opaque-pointers -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -no-opaque-pointers -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -no-opaque-pointers -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s typedef short short4 __attribute__((ext_vector_type(4))); @@ -21,18 +21,18 @@ generic int *generic *gengen; generic int *local *genloc; generic int *global *genglob; - // CHECK-DAG: call spir_func void @_Z3fooPU3AS1iS0_(i32 addrspace(1)* noundef undef, i32 addrspace(1)* noundef undef) + // CHECK-DAG: call spir_func void @_Z3fooPU3AS1iS0_(i32 addrspace(1)* noundef {{.*}}, i32 addrspace(1)* noundef {{.*}}) foo(a, b); - // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* noundef undef, i32 addrspace(4)* noundef undef) + // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* noundef {{.*}}, i32 addrspace(4)* noundef {{.*}}) foo(b, c); - // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* noundef undef, i32 addrspace(4)* noundef undef) + // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* noundef {{.*}}, i32 addrspace(4)* noundef {{.*}}) foo(a, d); - // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* noundef undef, i32 addrspace(4)* addrspace(4)* noundef undef) + // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* noundef {{.*}}, i32 addrspace(4)* addrspace(4)* noundef {{.*}}) bar(gengen, genloc); - // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* noundef undef, i32 addrspace(4)* addrspace(4)* noundef undef) + // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* noundef {{.*}}, i32 addrspace(4)* addrspace(4)* noundef {{.*}}) bar(gengen, genglob); - // CHECK-DAG: call spir_func void @_Z3barPU3AS1PU3AS4iS2_(i32 addrspace(4)* addrspace(1)* noundef undef, i32 addrspace(4)* addrspace(1)* noundef undef) + // CHECK-DAG: call spir_func void @_Z3barPU3AS1PU3AS4iS2_(i32 addrspace(4)* addrspace(1)* noundef {{.*}}, i32 addrspace(4)* addrspace(1)* noundef {{.*}}) bar(genglob, genglob); } @@ -40,8 +40,8 @@ void kernel test2() { short4 e0=0; - // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16> noundef zeroinitializer, i16 noundef signext 0, i16 noundef signext 255) + // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16> noundef {{.*}}, i16 noundef signext 0, i16 noundef signext 255) clamp(e0, 0, 255); - // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16> noundef zeroinitializer, <4 x i16> noundef zeroinitializer, <4 x i16> noundef zeroinitializer) + // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16> noundef {{.*}}, <4 x i16> noundef {{.*}}, <4 x i16> noundef {{.*}}) clamp(e0, e0, e0); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2900,6 +2900,15 @@ return nullptr; } +static bool callPassesUndefToPassingUndefUBParam(CallBase &Call) { + for (unsigned I = 0; I < Call.arg_size(); ++I) { + if (isa(Call.getArgOperand(I)) && Call.isPassingUndefUB(I)) { + return true; + } + } + return false; +} + bool InstCombinerImpl::annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) { // Note: We only handle cases which can't be driven from generic attributes @@ -3026,9 +3035,11 @@ // Calling a null function pointer is undefined if a null address isn't // dereferenceable. + // Passing undef/poison to any parameter where doing so is UB is undefined (of + // course). if ((isa(Callee) && !NullPointerIsDefined(Call.getFunction())) || - isa(Callee)) { + isa(Callee) || callPassesUndefToPassingUndefUBParam(Call)) { // If Call does not return void then replaceInstUsesWith poison. // This allows ValueHandlers and custom metadata to adjust itself. if (!Call.getType()->isVoidTy()) diff --git a/llvm/test/Transforms/InstCombine/call-undef.ll b/llvm/test/Transforms/InstCombine/call-undef.ll --- a/llvm/test/Transforms/InstCombine/call-undef.ll +++ b/llvm/test/Transforms/InstCombine/call-undef.ll @@ -8,7 +8,7 @@ define void @test1() { ; CHECK-LABEL: @test1( -; CHECK-NEXT: call void @c(i32 undef) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @c(i32 undef) @@ -17,7 +17,7 @@ define void @test2() { ; CHECK-LABEL: @test2( -; CHECK-NEXT: call void @c(i32 poison) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @c(i32 poison) @@ -26,7 +26,7 @@ define void @test3() { ; CHECK-LABEL: @test3( -; CHECK-NEXT: call void @e(i32 noundef undef) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @e(i32 noundef undef) @@ -35,7 +35,7 @@ define void @test4() { ; CHECK-LABEL: @test4( -; CHECK-NEXT: call void @e(i32 noundef poison) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @e(i32 noundef poison) @@ -44,7 +44,7 @@ define void @test5() { ; CHECK-LABEL: @test5( -; CHECK-NEXT: call void @d(ptr undef) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @d(ptr undef) @@ -53,7 +53,7 @@ define void @test6() { ; CHECK-LABEL: @test6( -; CHECK-NEXT: call void @d(ptr poison) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @d(ptr poison) @@ -62,7 +62,7 @@ define void @test7() { ; CHECK-LABEL: @test7( -; CHECK-NEXT: call void @f(ptr dereferenceable(1) undef) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @f(ptr dereferenceable(1) undef) @@ -71,7 +71,7 @@ define void @test8() { ; CHECK-LABEL: @test8( -; CHECK-NEXT: call void @f(ptr dereferenceable(1) poison) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret void ; call void @f(ptr dereferenceable(1) poison) diff --git a/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll b/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll --- a/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll +++ b/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: @test_out_of_bounds( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], 3 -; CHECK-NEXT: tail call void @llvm.assume(i1 poison) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret i32 [[AND1]] ; entry: @@ -20,7 +20,7 @@ define i128 @test_non64bit(i128 %a) { ; CHECK-LABEL: @test_non64bit( ; CHECK-NEXT: [[AND1:%.*]] = and i128 [[A:%.*]], 3 -; CHECK-NEXT: tail call void @llvm.assume(i1 poison) +; CHECK-NEXT: store i1 true, ptr poison, align 1 ; CHECK-NEXT: ret i128 [[AND1]] ; %and1 = and i128 %a, 3